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'));
 
 111     if ($aCMDResult['quiet'] ?? false) {
 
 112         $oCmd->addParams('--quiet');
 
 114     if ($aCMDResult['verbose'] ?? false) {
 
 115         $oCmd->addParams('--verbose');
 
 121 if ($aResult['init-updates']) {
 
 122     $oCmd = (clone($oNominatimCmd))->addParams('replication', '--init');
 
 124     if ($aResult['no-update-functions']) {
 
 125         $oCmd->addParams('--no-update-functions');
 
 131 if ($aResult['check-for-updates']) {
 
 132     exit((clone($oNominatimCmd))->addParams('replication', '--check-for-updates')->run());
 
 135 if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
 
 136     // import diffs and files directly (e.g. from osmosis --rri)
 
 137     $sNextFile = isset($aResult['import-diff']) ? $aResult['import-diff'] : $aResult['import-file'];
 
 139     if (!file_exists($sNextFile)) {
 
 140         fail("Cannot open $sNextFile\n");
 
 144     $oCMD = (clone $oOsm2pgsqlCmd)->addParams($sNextFile);
 
 145     echo $oCMD->escapedCmd()."\n";
 
 146     $iRet = $oCMD->run();
 
 149         fail("Error from osm2pgsql, $iRet\n");
 
 152     // Don't update the import status - we don't know what this file contains
 
 155 if ($aResult['calculate-postcodes']) {
 
 156     run((clone($oNominatimCmd))->addParams('refresh', '--postcodes'));
 
 159 $sTemporaryFile = CONST_InstallDir.'/osmosischange.osc';
 
 161 $bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-main-api'];
 
 163 if (isset($aResult['import-node']) && $aResult['import-node']) {
 
 165         $sContentURL = 'https://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
 
 167         $sContentURL = 'https://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
 
 171 if (isset($aResult['import-way']) && $aResult['import-way']) {
 
 173         $sContentURL = 'https://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
 
 175         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');%3E;);out%20meta;';
 
 179 if (isset($aResult['import-relation']) && $aResult['import-relation']) {
 
 181         $sContentURL = 'https://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
 
 183         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(rel(id:'.$aResult['import-relation'].');%3E;);out%20meta;';
 
 188     file_put_contents($sTemporaryFile, file_get_contents($sContentURL));
 
 193     // import generated change file
 
 195     $oCMD = (clone $oOsm2pgsqlCmd)->addParams($sTemporaryFile);
 
 196     echo $oCMD->escapedCmd()."\n";
 
 198     $iRet = $oCMD->run();
 
 200         fail("osm2pgsql exited with error level $iRet\n");
 
 204 if ($aResult['recompute-word-counts']) {
 
 205     run((clone($oNominatimCmd))->addParams('refresh', '--word-counts'));
 
 208 if ($aResult['index']) {
 
 209     run((clone $oNominatimCmd)
 
 210         ->addParams('index', '--minrank', $aResult['index-rank'])
 
 211         ->addParams('--threads', $aResult['index-instances']));
 
 214 if ($aResult['update-address-levels']) {
 
 215     run((clone($oNominatimCmd))->addParams('refresh', '--address-levels'));
 
 218 if ($aResult['recompute-importance']) {
 
 219     run((clone($oNominatimCmd))->addParams('refresh', '--importance'));
 
 222 if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
 
 223     $oCmd = (clone($oNominatimCmd))
 
 224               ->addParams('replication')
 
 225               ->addParams('--threads', $aResult['index-instances']);
 
 227     if (!$aResult['import-osmosis-all']) {
 
 228         $oCmd->addParams('--once');
 
 231     if ($aResult['no-index']) {
 
 232         $oCmd->addParams('--no-index');