]> git.openstreetmap.org Git - nominatim.git/blobdiff - utils/update.php
more sanity checks for pyosmium tools
[nominatim.git] / utils / update.php
index d729519a3ed5f3c9eb0d4f267094a702b7001eca..6caa7e4be95717a06c6c27d8cd7bca8021209d27 100755 (executable)
@@ -7,12 +7,13 @@ ini_set('memory_limit', '800M');
 
 $aCMDOptions
 = array(
 
 $aCMDOptions
 = array(
-   "Import / update / index osm data",
+   'Import / update / index osm data',
    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
 
    array('init-updates', '', 0, 1, 0, 0, 'bool', 'Set up database for updating'),
    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
 
    array('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('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'),
    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'),
@@ -33,6 +34,7 @@ $aCMDOptions
    array('index-instances', '', 0, 1, 1, 1, 'int', 'Number of indexing instances (threads)'),
 
    array('deduplicate', '', 0, 1, 0, 0, 'bool', 'Deduplicate tokens'),
    array('index-instances', '', 0, 1, 1, 1, 'int', 'Number of indexing instances (threads)'),
 
    array('deduplicate', '', 0, 1, 0, 0, 'bool', 'Deduplicate tokens'),
+   array('recompute-word-counts', '', 0, 1, 0, 0, 'bool', 'Compute frequency of full-word search terms'),
    array('no-npi', '', 0, 1, 0, 0, 'bool', '(obsolete)'),
   );
 getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
    array('no-npi', '', 0, 1, 0, 0, 'bool', '(obsolete)'),
   );
 getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
@@ -54,7 +56,7 @@ 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'];
     echo "WARNING: resetting cache memory to $iCacheMemory\n";
 }
 $sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas --number-processes 1 -C '.$iCacheMemory.' -O gazetteer -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'];
-if (!is_null(CONST_Osm2pgsql_Flatnode_File)) {
+if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) {
     $sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
 }
 
     $sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
 }
 
@@ -64,7 +66,23 @@ if ($aResult['init-updates']) {
     if ($sBaseState === false) {
         echo "\nCannot find state.txt file at the configured replication URL.\n";
         echo "Does the URL point to a directory containing OSM update data?\n\n";
     if ($sBaseState === false) {
         echo "\nCannot find state.txt file at the configured replication URL.\n";
         echo "Does the URL point to a directory containing OSM update data?\n\n";
-        fail("replication URL not reachable.");
+        fail('replication URL not reachable.');
+    }
+    // sanity check for pyosmium-get-changes
+    if (!CONST_Pyosmium_Binary) {
+        echo "\nCONST_Pyosmium_Binary not configured.\n";
+        echo "You need to install pyosmium and set up the path to pyosmium-get-changes\n";
+        echo "in your local settings file.\n\n";
+        fail('CONST_Pyosmium_Binary not configured');
+    }
+    $aOutput = 0;
+    $sCmd = CONST_Pyosmium_Binary.' --help';
+    exec($sCmd, $aOutput, $iRet);
+    if ($iRet != 0) {
+        echo "Cannot execute pyosmium-get-changes.\n";
+        echo "Make sure you have pyosmium installed correctly\n";
+        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;
     }
     $sSetup = CONST_InstallPath.'/utils/setup.php';
     $iRet = -1;
@@ -75,7 +93,7 @@ if ($aResult['init-updates']) {
 
     $sDatabaseDate = getDatabaseDate($oDB);
     if ($sDatabaseDate === false) {
 
     $sDatabaseDate = getDatabaseDate($oDB);
     if ($sDatabaseDate === false) {
-        fail("Cannot determine date of database.");
+        fail('Cannot determine date of database.');
     }
     $sWindBack = strftime('%Y-%m-%dT%H:%M:%SZ', strtotime($sDatabaseDate) - (3*60*60));
 
     }
     $sWindBack = strftime('%Y-%m-%dT%H:%M:%SZ', strtotime($sDatabaseDate) - (3*60*60));
 
@@ -89,14 +107,25 @@ if ($aResult['init-updates']) {
 
     pg_query($oDB->connection, 'TRUNCATE import_status');
     $sSQL = "INSERT INTO import_status (lastimportdate, sequence_id, indexed) VALUES('";
 
     pg_query($oDB->connection, 'TRUNCATE import_status');
     $sSQL = "INSERT INTO import_status (lastimportdate, sequence_id, indexed) VALUES('";
-    $sSQL .= $sDatabaseDate."',".$aOutput[0].", true)";
+    $sSQL .= $sDatabaseDate."',".$aOutput[0].', true)';
     if (!pg_query($oDB->connection, $sSQL)) {
     if (!pg_query($oDB->connection, $sSQL)) {
-        fail("Could not enter sequence into database.");
+        fail('Could not enter sequence into database.');
     }
 
     echo "Done. Database updates will start at sequence $aOutput[0] ($sWindBack)\n";
 }
 
     }
 
     echo "Done. Database updates will start at sequence $aOutput[0] ($sWindBack)\n";
 }
 
+if ($aResult['check-for-updates']) {
+    $aLastState = chksql($oDB->getRow('SELECT sequence_id FROM import_status'));
+
+    if (!$aLastState['sequence_id']) {
+        fail('Updates not set up. Please run ./utils/update.php --init-updates.');
+    }
+
+    system(CONST_BasePath.'/utils/check_server_for_updates.py '.CONST_Replication_Url.' '.$aLastState['sequence_id'], $iRet);
+    exit($iRet);
+}
+
 if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
     // import diffs and files directly (e.g. from osmosis --rri)
     $sNextFile = isset($aResult['import-diff']) ? $aResult['import-diff'] : $aResult['import-file'];
 if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
     // import diffs and files directly (e.g. from osmosis --rri)
     $sNextFile = isset($aResult['import-diff']) ? $aResult['import-diff'] : $aResult['import-file'];
@@ -118,7 +147,7 @@ if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
 }
 
 if ($aResult['calculate-postcodes']) {
 }
 
 if ($aResult['calculate-postcodes']) {
-    info("Update postcodes centroids");
+    info('Update postcodes centroids');
     $sTemplate = file_get_contents(CONST_BasePath.'/sql/update-postcodes.sql');
     runSQLScript($sTemplate, true, true);
 }
     $sTemplate = file_get_contents(CONST_BasePath.'/sql/update-postcodes.sql');
     runSQLScript($sTemplate, true, true);
 }
@@ -129,25 +158,25 @@ $bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-m
 $sContentURL = '';
 if (isset($aResult['import-node']) && $aResult['import-node']) {
     if ($bUseOSMApi) {
 $sContentURL = '';
 if (isset($aResult['import-node']) && $aResult['import-node']) {
     if ($bUseOSMApi) {
-        $sContentURL = 'http://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
+        $sContentURL = 'https://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
     } else {
     } else {
-        $sContentURL = 'http://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
+        $sContentURL = 'https://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
     }
 }
 
 if (isset($aResult['import-way']) && $aResult['import-way']) {
     if ($bUseOSMApi) {
     }
 }
 
 if (isset($aResult['import-way']) && $aResult['import-way']) {
     if ($bUseOSMApi) {
-        $sContentURL = 'http://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
+        $sContentURL = 'https://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
     } else {
     } else {
-        $sContentURL = 'http://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');node(w););out%20meta;';
+        $sContentURL = 'https://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');node(w););out%20meta;';
     }
 }
 
 if (isset($aResult['import-relation']) && $aResult['import-relation']) {
     if ($bUseOSMApi) {
     }
 }
 
 if (isset($aResult['import-relation']) && $aResult['import-relation']) {
     if ($bUseOSMApi) {
-        $sContentURLsModifyXMLstr = 'http://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
+        $sContentURLsModifyXMLstr = 'https://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
     } else {
     } else {
-        $sContentURL = 'http://overpass-api.de/api/interpreter?data=((rel('.$aResult['import-relation'].');way(r);node(w));node(r));out%20meta;';
+        $sContentURL = 'https://overpass-api.de/api/interpreter?data=((rel('.$aResult['import-relation'].');way(r);node(w));node(r));out%20meta;';
     }
 }
 
     }
 }
 
@@ -170,7 +199,7 @@ if ($aResult['deduplicate']) {
     $oDB =& getDB();
 
     if (getPostgresVersion($oDB) < 9.3) {
     $oDB =& getDB();
 
     if (getPostgresVersion($oDB) < 9.3) {
-        fail("ERROR: deduplicate is only currently supported in postgresql 9.3");
+        fail('ERROR: deduplicate is only currently supported in postgresql 9.3');
     }
 
     $sSQL = 'select partition from country_name order by country_code';
     }
 
     $sSQL = 'select partition from country_name order by country_code';
@@ -179,7 +208,7 @@ if ($aResult['deduplicate']) {
 
     // we don't care about empty search_name_* partitions, they can't contain mentions of duplicates
     foreach ($aPartitions as $i => $sPartition) {
 
     // we don't care about empty search_name_* partitions, they can't contain mentions of duplicates
     foreach ($aPartitions as $i => $sPartition) {
-        $sSQL = "select count(*) from search_name_".$sPartition;
+        $sSQL = 'select count(*) from search_name_'.$sPartition;
         $nEntries = chksql($oDB->getOne($sSQL));
         if ($nEntries == 0) {
             unset($aPartitions[$i]);
         $nEntries = chksql($oDB->getOne($sSQL));
         if ($nEntries == 0) {
             unset($aPartitions[$i]);
@@ -187,14 +216,14 @@ if ($aResult['deduplicate']) {
     }
 
     $sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' '";
     }
 
     $sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' '";
-    $sSQL .= " and class is null and type is null and country_code is null";
-    $sSQL .= " group by word_token having count(*) > 1 order by word_token";
+    $sSQL .= ' and class is null and type is null and country_code is null';
+    $sSQL .= ' group by word_token having count(*) > 1 order by word_token';
     $aDuplicateTokens = chksql($oDB->getAll($sSQL));
     foreach ($aDuplicateTokens as $aToken) {
         if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
     $aDuplicateTokens = chksql($oDB->getAll($sSQL));
     foreach ($aDuplicateTokens as $aToken) {
         if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
-        echo "Deduping ".$aToken['word_token']."\n";
-        $sSQL = "select word_id,";
-        $sSQL .= " (select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num";
+        echo 'Deduping '.$aToken['word_token']."\n";
+        $sSQL = 'select word_id,';
+        $sSQL .= ' (select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num';
         $sSQL .= " from word where word_token = '".$aToken['word_token'];
         $sSQL .= "' and class is null and type is null and country_code is null order by num desc";
         $aTokenSet = chksql($oDB->getAll($sSQL));
         $sSQL .= " from word where word_token = '".$aToken['word_token'];
         $sSQL .= "' and class is null and type is null and country_code is null order by num desc";
         $aTokenSet = chksql($oDB->getAll($sSQL));
@@ -203,40 +232,46 @@ if ($aResult['deduplicate']) {
         $iKeepID = $aKeep['word_id'];
 
         foreach ($aTokenSet as $aRemove) {
         $iKeepID = $aKeep['word_id'];
 
         foreach ($aTokenSet as $aRemove) {
-            $sSQL = "update search_name set";
-            $sSQL .= " name_vector = array_replace(name_vector,".$aRemove['word_id'].",".$iKeepID."),";
-            $sSQL .= " nameaddress_vector = array_replace(nameaddress_vector,".$aRemove['word_id'].",".$iKeepID.")";
-            $sSQL .= " where name_vector @> ARRAY[".$aRemove['word_id']."]";
+            $sSQL = 'update search_name set';
+            $sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.'),';
+            $sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
+            $sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
             chksql($oDB->query($sSQL));
 
             chksql($oDB->query($sSQL));
 
-            $sSQL = "update search_name set";
-            $sSQL .= " nameaddress_vector = array_replace(nameaddress_vector,".$aRemove['word_id'].",".$iKeepID.")";
-            $sSQL .= " where nameaddress_vector @> ARRAY[".$aRemove['word_id']."]";
+            $sSQL = 'update search_name set';
+            $sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
+            $sSQL .= ' where nameaddress_vector @> ARRAY['.$aRemove['word_id'].']';
             chksql($oDB->query($sSQL));
 
             chksql($oDB->query($sSQL));
 
-            $sSQL = "update location_area_country set";
-            $sSQL .= " keywords = array_replace(keywords,".$aRemove['word_id'].",".$iKeepID.")";
-            $sSQL .= " where keywords @> ARRAY[".$aRemove['word_id']."]";
+            $sSQL = 'update location_area_country set';
+            $sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
+            $sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
             chksql($oDB->query($sSQL));
 
             foreach ($aPartitions as $sPartition) {
             chksql($oDB->query($sSQL));
 
             foreach ($aPartitions as $sPartition) {
-                $sSQL = "update search_name_".$sPartition." set";
-                $sSQL .= " name_vector = array_replace(name_vector,".$aRemove['word_id'].",".$iKeepID.")";
-                $sSQL .= " where name_vector @> ARRAY[".$aRemove['word_id']."]";
+                $sSQL = 'update search_name_'.$sPartition.' set';
+                $sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.')';
+                $sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
                 chksql($oDB->query($sSQL));
 
                 chksql($oDB->query($sSQL));
 
-                $sSQL = "update location_area_country set";
-                $sSQL .= " keywords = array_replace(keywords,".$aRemove['word_id'].",".$iKeepID.")";
-                $sSQL .= " where keywords @> ARRAY[".$aRemove['word_id']."]";
+                $sSQL = 'update location_area_country set';
+                $sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
+                $sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
                 chksql($oDB->query($sSQL));
             }
 
                 chksql($oDB->query($sSQL));
             }
 
-            $sSQL = "delete from word where word_id = ".$aRemove['word_id'];
+            $sSQL = 'delete from word where word_id = '.$aRemove['word_id'];
             chksql($oDB->query($sSQL));
         }
     }
 }
 
             chksql($oDB->query($sSQL));
         }
     }
 }
 
+if ($aResult['recompute-word-counts']) {
+    info('Recompute frequency of full-word search terms');
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/words_from_search_name.sql');
+    runSQLScript($sTemplate, true, true);
+}
+
 if ($aResult['index']) {
     passthru(CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank']);
 }
 if ($aResult['index']) {
     passthru(CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank']);
 }
@@ -244,7 +279,8 @@ if ($aResult['index']) {
 if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
     //
     if (strpos(CONST_Replication_Url, 'download.geofabrik.de') !== false && CONST_Replication_Update_Interval < 86400) {
 if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
     //
     if (strpos(CONST_Replication_Url, 'download.geofabrik.de') !== false && CONST_Replication_Update_Interval < 86400) {
-        fail("Error: Update interval too low for download.geofabrik.de.  Please check install documentation (http://wiki.openstreetmap.org/wiki/Nominatim/Installation#Updates)\n");
+        fail('Error: Update interval too low for download.geofabrik.de. ' .
+             "Please check install documentation (http://nominatim.org/release-docs/latest/Import-and-Update#setting-up-the-update-process)\n");
     }
 
     $sImportFile = CONST_InstallPath.'/osmosischange.osc';
     }
 
     $sImportFile = CONST_InstallPath.'/osmosischange.osc';
@@ -281,7 +317,9 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
                 $iNextSeq = (int) $aLastState['sequence_id'];
                 unset($aOutput);
                 echo "$sCMDDownload -I $iNextSeq\n";
                 $iNextSeq = (int) $aLastState['sequence_id'];
                 unset($aOutput);
                 echo "$sCMDDownload -I $iNextSeq\n";
-                unlink($sImportFile);
+                if (file_exists($sImportFile)) {
+                    unlink($sImportFile);
+                }
                 exec($sCMDDownload.' -I '.$iNextSeq, $aOutput, $iResult);
 
                 if ($iResult == 3) {
                 exec($sCMDDownload.' -I '.$iNextSeq, $aOutput, $iResult);
 
                 if ($iResult == 3) {
@@ -360,7 +398,7 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
             $oDB->query($sSQL);
             echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
 
             $oDB->query($sSQL);
             echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
 
-            $sSQL = "update import_status set indexed = true";
+            $sSQL = 'update import_status set indexed = true';
             $oDB->query($sSQL);
         }
 
             $oDB->query($sSQL);
         }