2 @define('CONST_LibDir', dirname(dirname(__FILE__)));
 
   4 require_once(CONST_LibDir.'/init-cmd.php');
 
   5 require_once(CONST_LibDir.'/setup_functions.php');
 
   6 require_once(CONST_LibDir.'/setup/SetupClass.php');
 
   8 ini_set('memory_limit', '800M');
 
  10 use Nominatim\Setup\SetupFunctions as SetupFunctions;
 
  12 // (long-opt, short-opt, min-occurs, max-occurs, num-arguments, num-arguments, type, help)
 
  15    'Import / update / index osm data',
 
  16    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
 
  17    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
 
  18    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
 
  20    array('init-updates', '', 0, 1, 0, 0, 'bool', 'Set up database for updating'),
 
  21    array('check-for-updates', '', 0, 1, 0, 0, 'bool', 'Check if new updates are available'),
 
  22    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)'),
 
  23    array('import-osmosis', '', 0, 1, 0, 0, 'bool', 'Import updates once'),
 
  24    array('import-osmosis-all', '', 0, 1, 0, 0, 'bool', 'Import updates forever'),
 
  25    array('no-index', '', 0, 1, 0, 0, 'bool', 'Do not index the new data'),
 
  27    array('calculate-postcodes', '', 0, 1, 0, 0, 'bool', 'Update postcode centroid table'),
 
  29    array('import-file', '', 0, 1, 1, 1, 'realpath', 'Re-import data from an OSM file'),
 
  30    array('import-diff', '', 0, 1, 1, 1, 'realpath', 'Import a diff (osc) file from local file system'),
 
  31    array('osm2pgsql-cache', '', 0, 1, 1, 1, 'int', 'Cache size used by osm2pgsql'),
 
  33    array('import-node', '', 0, 1, 1, 1, 'int', 'Re-import node'),
 
  34    array('import-way', '', 0, 1, 1, 1, 'int', 'Re-import way'),
 
  35    array('import-relation', '', 0, 1, 1, 1, 'int', 'Re-import relation'),
 
  36    array('import-from-main-api', '', 0, 1, 0, 0, 'bool', 'Use OSM API instead of Overpass to download objects'),
 
  38    array('index', '', 0, 1, 0, 0, 'bool', 'Index'),
 
  39    array('index-rank', '', 0, 1, 1, 1, 'int', 'Rank to start indexing from'),
 
  40    array('index-instances', '', 0, 1, 1, 1, 'int', 'Number of indexing instances (threads)'),
 
  42    array('recompute-word-counts', '', 0, 1, 0, 0, 'bool', 'Compute frequency of full-word search terms'),
 
  43    array('update-address-levels', '', 0, 1, 0, 0, 'bool', 'Reimport address level configuration (EXPERT)'),
 
  44    array('recompute-importance', '', 0, 1, 0, 0, 'bool', 'Recompute place importances'),
 
  46    array('project-dir', '', 0, 1, 1, 1, 'realpath', 'Base directory of the Nominatim installation (default: .)'),
 
  49 getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
 
  51 loadSettings($aCMDResult['project-dir'] ?? getcwd());
 
  54 if (!isset($aResult['index-instances'])) $aResult['index-instances'] = 1;
 
  55 if (!isset($aResult['index-rank'])) $aResult['index-rank'] = 0;
 
  57 date_default_timezone_set('Etc/UTC');
 
  59 $oDB = new Nominatim\DB();
 
  61 $fPostgresVersion = $oDB->getPostgresVersion();
 
  63 $aDSNInfo = Nominatim\DB::parseDSN(getSetting('DATABASE_DSN'));
 
  64 if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
 
  66 // cache memory to be used by osm2pgsql, should not be more than the available memory
 
  67 $iCacheMemory = (isset($aResult['osm2pgsql-cache'])?$aResult['osm2pgsql-cache']:2000);
 
  68 if ($iCacheMemory + 500 > getTotalMemoryMB()) {
 
  69     $iCacheMemory = getCacheMemoryMB();
 
  70     echo "WARNING: resetting cache memory to $iCacheMemory\n";
 
  73 $oOsm2pgsqlCmd = (new \Nominatim\Shell(getOsm2pgsqlBinary()))
 
  74                  ->addParams('--hstore')
 
  75                  ->addParams('--latlong')
 
  76                  ->addParams('--append')
 
  78                  ->addParams('--with-forward-dependencies', 'false')
 
  79                  ->addParams('--log-progress', 'true')
 
  80                  ->addParams('--number-processes', 1)
 
  81                  ->addParams('--cache', $iCacheMemory)
 
  82                  ->addParams('--output', 'gazetteer')
 
  83                  ->addParams('--style', getImportStyle())
 
  84                  ->addParams('--database', $aDSNInfo['database'])
 
  85                  ->addParams('--port', $aDSNInfo['port']);
 
  87 if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
 
  88     $oOsm2pgsqlCmd->addParams('--host', $aDSNInfo['hostspec']);
 
  90 if (isset($aDSNInfo['username']) && $aDSNInfo['username']) {
 
  91     $oOsm2pgsqlCmd->addParams('--user', $aDSNInfo['username']);
 
  93 if (isset($aDSNInfo['password']) && $aDSNInfo['password']) {
 
  94     $oOsm2pgsqlCmd->addEnvPair('PGPASSWORD', $aDSNInfo['password']);
 
  96 if (getSetting('FLATNODE_FILE')) {
 
  97     $oOsm2pgsqlCmd->addParams('--flat-nodes', getSetting('FLATNODE_FILE'));
 
  99 if ($fPostgresVersion >= 11.0) {
 
 100     $oOsm2pgsqlCmd->addEnvPair(
 
 102         '-c jit=off -c max_parallel_workers_per_gather=0'
 
 106 $oNominatimCmd = new \Nominatim\Shell(getSetting('NOMINATIM_TOOL'));
 
 107 if ($aResult['quiet']) {
 
 108     $oNominatimCmd->addParams('--quiet');
 
 110 if ($aResult['verbose']) {
 
 111     $oNominatimCmd->addParams('--verbose');
 
 115 if ($aResult['init-updates']) {
 
 116     $oCmd = (clone($oNominatimCmd))->addParams('replication', '--init');
 
 118     if ($aResult['no-update-functions']) {
 
 119         $oCmd->addParams('--no-update-functions');
 
 125 if ($aResult['check-for-updates']) {
 
 126     exit((clone($oNominatimCmd))->addParams('replication', '--check-for-updates')->run());
 
 129 if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
 
 130     // import diffs and files directly (e.g. from osmosis --rri)
 
 131     $sNextFile = isset($aResult['import-diff']) ? $aResult['import-diff'] : $aResult['import-file'];
 
 133     if (!file_exists($sNextFile)) {
 
 134         fail("Cannot open $sNextFile\n");
 
 138     $oCMD = (clone $oOsm2pgsqlCmd)->addParams($sNextFile);
 
 139     echo $oCMD->escapedCmd()."\n";
 
 140     $iRet = $oCMD->run();
 
 143         fail("Error from osm2pgsql, $iRet\n");
 
 146     // Don't update the import status - we don't know what this file contains
 
 149 if ($aResult['calculate-postcodes']) {
 
 150     (clone($oNominatimCmd))->addParams('refresh', '--postcodes')->run();
 
 153 $sTemporaryFile = CONST_InstallDir.'/osmosischange.osc';
 
 155 $bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-main-api'];
 
 157 if (isset($aResult['import-node']) && $aResult['import-node']) {
 
 159         $sContentURL = 'https://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
 
 161         $sContentURL = 'https://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
 
 165 if (isset($aResult['import-way']) && $aResult['import-way']) {
 
 167         $sContentURL = 'https://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
 
 169         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');%3E;);out%20meta;';
 
 173 if (isset($aResult['import-relation']) && $aResult['import-relation']) {
 
 175         $sContentURL = 'https://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
 
 177         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(rel(id:'.$aResult['import-relation'].');%3E;);out%20meta;';
 
 182     file_put_contents($sTemporaryFile, file_get_contents($sContentURL));
 
 187     // import generated change file
 
 189     $oCMD = (clone $oOsm2pgsqlCmd)->addParams($sTemporaryFile);
 
 190     echo $oCMD->escapedCmd()."\n";
 
 192     $iRet = $oCMD->run();
 
 194         fail("osm2pgsql exited with error level $iRet\n");
 
 198 if ($aResult['recompute-word-counts']) {
 
 199     (clone($oNominatimCmd))->addParams('refresh', '--word-counts')->run();
 
 202 if ($aResult['index']) {
 
 203     (clone $oNominatimCmd)
 
 204         ->addParams('index', '--minrank', $aResult['index-rank'])
 
 205         ->addParams('--threads', $aResult['index-instances'])
 
 209 if ($aResult['update-address-levels']) {
 
 210     (clone($oNominatimCmd))->addParams('refresh', '--address-levels')->run();
 
 213 if ($aResult['recompute-importance']) {
 
 214     echo "Updating importance values for database.\n";
 
 215     $oDB = new Nominatim\DB();
 
 218     $sSQL = 'ALTER TABLE placex DISABLE TRIGGER ALL;';
 
 219     $sSQL .= 'UPDATE placex SET (wikipedia, importance) =';
 
 220     $sSQL .= '   (SELECT wikipedia, importance';
 
 221     $sSQL .= '    FROM compute_importance(extratags, country_code, osm_type, osm_id));';
 
 222     $sSQL .= 'UPDATE placex s SET wikipedia = d.wikipedia, importance = d.importance';
 
 223     $sSQL .= ' FROM placex d';
 
 224     $sSQL .= ' WHERE s.place_id = d.linked_place_id and d.wikipedia is not null';
 
 225     $sSQL .= '       and (s.wikipedia is null or s.importance < d.importance);';
 
 226     $sSQL .= 'ALTER TABLE placex ENABLE TRIGGER ALL;';
 
 230 if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
 
 231     $oCmd = (clone($oNominatimCmd))
 
 232               ->addParams('replication')
 
 233               ->addParams('--threads', $aResult['index-instances']);
 
 235     if (!$aResult['import-osmosis-all']) {
 
 236         $oCmd->addParams('--once');
 
 239     if ($aResult['no-index']) {
 
 240         $oCmd->addParams('--no-index');