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;
 
  56 if (!isset($aResult['index-rank'])) $aResult['index-rank'] = 0;
 
  58 date_default_timezone_set('Etc/UTC');
 
  60 $oDB = new Nominatim\DB();
 
  62 $fPostgresVersion = $oDB->getPostgresVersion();
 
  64 $aDSNInfo = Nominatim\DB::parseDSN(getSetting('DATABASE_DSN'));
 
  65 if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
 
  67 // cache memory to be used by osm2pgsql, should not be more than the available memory
 
  68 $iCacheMemory = (isset($aResult['osm2pgsql-cache'])?$aResult['osm2pgsql-cache']:2000);
 
  69 if ($iCacheMemory + 500 > getTotalMemoryMB()) {
 
  70     $iCacheMemory = getCacheMemoryMB();
 
  71     echo "WARNING: resetting cache memory to $iCacheMemory\n";
 
  74 $oOsm2pgsqlCmd = (new \Nominatim\Shell(getOsm2pgsqlBinary()))
 
  75                  ->addParams('--hstore')
 
  76                  ->addParams('--latlong')
 
  77                  ->addParams('--append')
 
  79                  ->addParams('--with-forward-dependencies', 'false')
 
  80                  ->addParams('--log-progress', 'true')
 
  81                  ->addParams('--number-processes', 1)
 
  82                  ->addParams('--cache', $iCacheMemory)
 
  83                  ->addParams('--output', 'gazetteer')
 
  84                  ->addParams('--style', getImportStyle())
 
  85                  ->addParams('--database', $aDSNInfo['database'])
 
  86                  ->addParams('--port', $aDSNInfo['port']);
 
  88 if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
 
  89     $oOsm2pgsqlCmd->addParams('--host', $aDSNInfo['hostspec']);
 
  91 if (isset($aDSNInfo['username']) && $aDSNInfo['username']) {
 
  92     $oOsm2pgsqlCmd->addParams('--user', $aDSNInfo['username']);
 
  94 if (isset($aDSNInfo['password']) && $aDSNInfo['password']) {
 
  95     $oOsm2pgsqlCmd->addEnvPair('PGPASSWORD', $aDSNInfo['password']);
 
  97 if (getSetting('FLATNODE_FILE')) {
 
  98     $oOsm2pgsqlCmd->addParams('--flat-nodes', getSetting('FLATNODE_FILE'));
 
 100 if ($fPostgresVersion >= 11.0) {
 
 101     $oOsm2pgsqlCmd->addEnvPair(
 
 103         '-c jit=off -c max_parallel_workers_per_gather=0'
 
 107 $oNominatimCmd = new \Nominatim\Shell(getSetting('NOMINATIM_TOOL'));
 
 112     if ($aCMDResult['quiet'] ?? false) {
 
 113         $oCmd->addParams('--quiet');
 
 115     if ($aCMDResult['verbose'] ?? false) {
 
 116         $oCmd->addParams('--verbose');
 
 122 if ($aResult['init-updates']) {
 
 123     $oCmd = (clone($oNominatimCmd))->addParams('replication', '--init');
 
 125     if ($aResult['no-update-functions']) {
 
 126         $oCmd->addParams('--no-update-functions');
 
 132 if ($aResult['check-for-updates']) {
 
 133     exit((clone($oNominatimCmd))->addParams('replication', '--check-for-updates')->run());
 
 136 if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
 
 137     // import diffs and files directly (e.g. from osmosis --rri)
 
 138     $sNextFile = isset($aResult['import-diff']) ? $aResult['import-diff'] : $aResult['import-file'];
 
 140     if (!file_exists($sNextFile)) {
 
 141         fail("Cannot open $sNextFile\n");
 
 145     $oCMD = (clone $oOsm2pgsqlCmd)->addParams($sNextFile);
 
 146     echo $oCMD->escapedCmd()."\n";
 
 147     $iRet = $oCMD->run();
 
 150         fail("Error from osm2pgsql, $iRet\n");
 
 153     // Don't update the import status - we don't know what this file contains
 
 156 if ($aResult['calculate-postcodes']) {
 
 157     run((clone($oNominatimCmd))->addParams('refresh', '--postcodes'));
 
 160 $sTemporaryFile = CONST_InstallDir.'/osmosischange.osc';
 
 162 $bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-main-api'];
 
 164 if (isset($aResult['import-node']) && $aResult['import-node']) {
 
 166         $sContentURL = 'https://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
 
 168         $sContentURL = 'https://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
 
 172 if (isset($aResult['import-way']) && $aResult['import-way']) {
 
 174         $sContentURL = 'https://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
 
 176         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');%3E;);out%20meta;';
 
 180 if (isset($aResult['import-relation']) && $aResult['import-relation']) {
 
 182         $sContentURL = 'https://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
 
 184         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(rel(id:'.$aResult['import-relation'].');%3E;);out%20meta;';
 
 189     file_put_contents($sTemporaryFile, file_get_contents($sContentURL));
 
 194     // import generated change file
 
 196     $oCMD = (clone $oOsm2pgsqlCmd)->addParams($sTemporaryFile);
 
 197     echo $oCMD->escapedCmd()."\n";
 
 199     $iRet = $oCMD->run();
 
 201         fail("osm2pgsql exited with error level $iRet\n");
 
 205 if ($aResult['recompute-word-counts']) {
 
 206     run((clone($oNominatimCmd))->addParams('refresh', '--word-counts'));
 
 209 if ($aResult['index']) {
 
 210     run((clone $oNominatimCmd)
 
 211         ->addParams('index', '--minrank', $aResult['index-rank'])
 
 212         ->addParams('--threads', $aResult['index-instances']));
 
 215 if ($aResult['update-address-levels']) {
 
 216     run((clone($oNominatimCmd))->addParams('refresh', '--address-levels'));
 
 219 if ($aResult['recompute-importance']) {
 
 220     run((clone($oNominatimCmd))->addParams('refresh', '--importance'));
 
 223 if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
 
 224     $oCmd = (clone($oNominatimCmd))
 
 225               ->addParams('replication')
 
 226               ->addParams('--threads', $aResult['index-instances']);
 
 228     if (!$aResult['import-osmosis-all']) {
 
 229         $oCmd->addParams('--once');
 
 232     if ($aResult['no-index']) {
 
 233         $oCmd->addParams('--no-index');