X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/cc24d998e48925bd43730342b0428986f7a51ec8..71883fc3410127b97ae0524ca07a187e125d7801:/utils/setup.php diff --git a/utils/setup.php b/utils/setup.php index 3fe5a7ab..a1d8ae5d 100755 --- a/utils/setup.php +++ b/utils/setup.php @@ -22,15 +22,18 @@ array('create-functions', '', 0, 1, 0, 0, 'bool', 'Create functions'), array('enable-diff-updates', '', 0, 1, 0, 0, 'bool', 'Turn on the code required to make diff updates work'), array('enable-debug-statements', '', 0, 1, 0, 0, 'bool', 'Include debug warning statements in pgsql commands'), + array('ignore-errors', '', 0, 1, 0, 0, 'bool', 'Continue import even when errors in SQL are present (EXPERT)'), array('create-minimal-tables', '', 0, 1, 0, 0, 'bool', 'Create minimal main tables'), array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create main tables'), - array('create-partitions', '', 0, 1, 0, 0, 'bool', 'Create required partition tables and triggers'), + array('create-partition-tables', '', 0, 1, 0, 0, 'bool', 'Create required partition tables'), + array('create-partition-functions', '', 0, 1, 0, 0, 'bool', 'Create required partition triggers'), + array('no-partitions', '', 0, 1, 0, 0, 'bool', "Do not partition search indices (speeds up import of single country extracts)"), array('import-wikipedia-articles', '', 0, 1, 0, 0, 'bool', 'Import wikipedia article dump'), array('load-data', '', 0, 1, 0, 0, 'bool', 'Copy data to live tables from import table'), array('disable-token-precalc', '', 0, 1, 0, 0, 'bool', 'Disable name precalculation (EXPERT)'), array('import-tiger-data', '', 0, 1, 0, 0, 'bool', 'Import tiger data (not included in \'all\')'), array('calculate-postcodes', '', 0, 1, 0, 0, 'bool', 'Calculate postcode centroids'), - array('create-roads', '', 0, 1, 0, 0, 'bool', 'Calculate postcode centroids'), + array('create-roads', '', 0, 1, 0, 0, 'bool', ''), array('osmosis-init', '', 0, 1, 0, 0, 'bool', 'Generate default osmosis configuration'), array('index', '', 0, 1, 0, 0, 'bool', 'Index the data'), array('index-noanalyse', '', 0, 1, 0, 0, 'bool', 'Do not perform analyse operations during index (EXPERT)'), @@ -95,7 +98,7 @@ { fail('database already exists ('.CONST_Database_DSN.')'); } - passthru('createdb -E UTF-8 '.$aDSNInfo['database']); + passthruCheckReturn('createdb -E UTF-8 -p '.$aDSNInfo['port'].' '.$aDSNInfo['database']); } if ($aCMDResult['setup-db'] || $aCMDResult['all']) @@ -105,7 +108,16 @@ // TODO: path detection, detection memory, etc. $oDB =& getDB(); - passthru('createlang plpgsql '.$aDSNInfo['database']); + + $sVersionString = $oDB->getOne('select version()'); + preg_match('#PostgreSQL ([0-9]+)[.]([0-9]+)[.]([0-9]+) #', $sVersionString, $aMatches); + if (CONST_Postgresql_Version != $aMatches[1].'.'.$aMatches[2]) + { + echo "ERROR: PostgreSQL version is not correct. Expected ".CONST_Postgresql_Version." found ".$aMatches[1].'.'.$aMatches[2]."\n"; + exit; + } + + passthru('createlang plpgsql -p '.$aDSNInfo['port'].' '.$aDSNInfo['database']); $pgver = (float) CONST_Postgresql_Version; if ($pgver < 9.1) { pgsqlRunScriptFile(CONST_Path_Postgresql_Contrib.'/hstore.sql'); @@ -113,16 +125,53 @@ } else { pgsqlRunScript('CREATE EXTENSION hstore'); } - pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/postgis.sql'); - pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/spatial_ref_sys.sql'); + + $fPostgisVersion = (float) CONST_Postgis_Version; + if ($fPostgisVersion < 2.0) { + pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/postgis.sql'); + pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/spatial_ref_sys.sql'); + } else { + pgsqlRunScript('CREATE EXTENSION postgis'); + } + if ($fPostgisVersion < 2.1) { + // Function was renamed in 2.1 and throws an annoying deprecation warning + pgsqlRunScript('ALTER FUNCTION st_line_interpolate_point(geometry, double precision) RENAME TO ST_LineInterpolatePoint'); + } + $sVersionString = $oDB->getOne('select postgis_full_version()'); + preg_match('#POSTGIS="([0-9]+)[.]([0-9]+)[.]([0-9]+)( r([0-9]+))?"#', $sVersionString, $aMatches); + if (CONST_Postgis_Version != $aMatches[1].'.'.$aMatches[2]) + { + echo "ERROR: PostGIS version is not correct. Expected ".CONST_Postgis_Version." found ".$aMatches[1].'.'.$aMatches[2]."\n"; + exit; + } + pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql'); pgsqlRunScriptFile(CONST_BasePath.'/data/country_naturalearthdata.sql'); pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql'); - pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode.sql'); + pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_table.sql'); + if (file_exists(CONST_BasePath.'/data/gb_postcode_data.sql.gz')) + { + pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_data.sql.gz'); + } + else + { + echo "WARNING: external UK postcode table not found.\n"; + } pgsqlRunScriptFile(CONST_BasePath.'/data/us_statecounty.sql'); pgsqlRunScriptFile(CONST_BasePath.'/data/us_state.sql'); pgsqlRunScriptFile(CONST_BasePath.'/data/us_postcode.sql'); - pgsqlRunScriptFile(CONST_BasePath.'/data/worldboundaries.sql'); + + if ($aCMDResult['no-partitions']) + { + pgsqlRunScript('update country_name set partition = 0'); + } + + // the following will be needed by create_functions later but + // is only defined in the subsequently called create_tables. + // Create dummies here that will be overwritten by the proper + // versions in create-tables. + pgsqlRunScript('CREATE TABLE place_boundingbox ()'); + pgsqlRunScript('create type wikipedia_article_match as ()'); } if ($aCMDResult['import-data'] || $aCMDResult['all']) @@ -136,8 +185,14 @@ echo "Please download and build osm2pgsql.\nIf it is already installed, check the path in your local settings (settings/local.php) file.\n"; fail("osm2pgsql not found in '$osm2pgsql'"); } + + if (!is_null(CONST_Osm2pgsql_Flatnode_File)) + { + $osm2pgsql .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File; + } $osm2pgsql .= ' -lsc -O gazetteer --hstore'; $osm2pgsql .= ' -C '.$iCacheMemory; + $osm2pgsql .= ' -P '.$aDSNInfo['port']; $osm2pgsql .= ' -d '.$aDSNInfo['database'].' '.$aCMDResult['osm-file']; passthruCheckReturn($osm2pgsql); @@ -158,6 +213,7 @@ $sTemplate = str_replace('{modulepath}', CONST_BasePath.'/module', $sTemplate); if ($aCMDResult['enable-diff-updates']) $sTemplate = str_replace('RETURN NEW; -- @DIFFUPDATES@', '--', $sTemplate); if ($aCMDResult['enable-debug-statements']) $sTemplate = str_replace('--DEBUG:', '', $sTemplate); + if (CONST_Limit_Reindexing) $sTemplate = str_replace('--LIMIT INDEXING:', '', $sTemplate); pgsqlRunScript($sTemplate); } @@ -203,20 +259,49 @@ pgsqlRunScript($sTemplate); } - if ($aCMDResult['create-partitions'] || $aCMDResult['all']) + if ($aCMDResult['create-partition-tables'] || $aCMDResult['all']) + { + echo "Partition Tables\n"; + $bDidSomething = true; + $oDB =& getDB(); + $sSQL = 'select distinct partition from country_name'; + $aPartitions = $oDB->getCol($sSQL); + if (PEAR::isError($aPartitions)) + { + fail($aPartitions->getMessage()); + } + if (!$aCMDResult['no-partitions']) $aPartitions[] = 0; + + $sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-tables.src.sql'); + preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER); + foreach($aMatches as $aMatch) + { + $sResult = ''; + foreach($aPartitions as $sPartitionName) + { + $sResult .= str_replace('-partition-', $sPartitionName, $aMatch[1]); + } + $sTemplate = str_replace($aMatch[0], $sResult, $sTemplate); + } + + pgsqlRunScript($sTemplate); + } + + + if ($aCMDResult['create-partition-functions'] || $aCMDResult['all']) { - echo "Partitions\n"; + echo "Partition Functions\n"; $bDidSomething = true; $oDB =& getDB(); - $sSQL = 'select partition from country_name order by country_code'; + $sSQL = 'select distinct partition from country_name'; $aPartitions = $oDB->getCol($sSQL); if (PEAR::isError($aPartitions)) { fail($aPartitions->getMessage()); } - $aPartitions[] = 0; + if (!$aCMDResult['no-partitions']) $aPartitions[] = 0; - $sTemplate = file_get_contents(CONST_BasePath.'/sql/partitions.src.sql'); + $sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-functions.src.sql'); preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER); foreach($aMatches as $aMatch) { @@ -284,13 +369,13 @@ if (!pg_query($oDB->connection, 'CREATE SEQUENCE seq_place start 100000')) fail(pg_last_error($oDB->connection)); echo '.'; - $sSQL = 'select partition from country_name order by country_code'; + $sSQL = 'select distinct partition from country_name'; $aPartitions = $oDB->getCol($sSQL); if (PEAR::isError($aPartitions)) { fail($aPartitions->getMessage()); } - $aPartitions[] = 0; + if (!$aCMDResult['no-partitions']) $aPartitions[] = 0; foreach($aPartitions as $sPartition) { if (!pg_query($oDB->connection, 'TRUNCATE location_road_'.$sPartition)) fail(pg_last_error($oDB->connection)); @@ -314,7 +399,7 @@ { $aDBInstances[$i] =& getDB(true); $sSQL = 'insert into placex (osm_type, osm_id, class, type, name, admin_level, '; - $sSQL .= 'housenumber, street, isin, postcode, country_code, extratags, '; + $sSQL .= 'housenumber, street, addr_place, isin, postcode, country_code, extratags, '; $sSQL .= 'geometry) select * from place where osm_id % '.$iInstances.' = '.$i; if ($aCMDResult['verbose']) echo "$sSQL\n"; if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection)); @@ -446,71 +531,83 @@ $bDidSomething = true; $oDB =& getDB(); - if (!file_exists(CONST_Osmosis_Binary)) fail("please download osmosis"); - if (file_exists(CONST_BasePath.'/settings/configuration.txt')) + if (!file_exists(CONST_Osmosis_Binary)) { - echo "settings/configuration.txt already exists\n"; + echo "Please download osmosis.\nIf it is already installed, check the path in your local settings (settings/local.php) file.\n"; + if (!$aCMDResult['all']) + { + fail("osmosis not found in '".CONST_Osmosis_Binary."'"); + } } else { - passthru(CONST_Osmosis_Binary.' --read-replication-interval-init '.CONST_BasePath.'/settings'); - // server layout changed afer license change, fix path to minutely diffs - passthru("sed -i 's:minute-replicate:replication/minute:' ".CONST_BasePath.'/settings/configuration.txt'); - } - - // Find the last node in the DB - $iLastOSMID = $oDB->getOne("select max(osm_id) as osm_id from place where osm_type = 'N'"); - - // Lookup the timestamp that node was created (less 3 hours for margin for changsets to be closed) - $sLastNodeURL = 'http://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID; - $sLastNodeXML = file_get_contents($sLastNodeURL); - preg_match('#timestamp="(([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z)"#', $sLastNodeXML, $aLastNodeDate); - $iLastNodeTimestamp = strtotime($aLastNodeDate[1]) - (3*60*60); - + if (file_exists(CONST_BasePath.'/settings/configuration.txt')) + { + echo "settings/configuration.txt already exists\n"; + } + else + { + passthru(CONST_Osmosis_Binary.' --read-replication-interval-init '.CONST_BasePath.'/settings'); + // update osmosis configuration.txt with our settings + passthru("sed -i 's!baseUrl=.*!baseUrl=".CONST_Replication_Url."!' ".CONST_BasePath.'/settings/configuration.txt'); + passthru("sed -i 's:maxInterval = .*:maxInterval = ".CONST_Replication_MaxInterval.":' ".CONST_BasePath.'/settings/configuration.txt'); + } - // Search for the correct state file - uses file timestamps - $sRepURL = 'http://planet.openstreetmap.org/replication/minute/'; - $sRep = file_get_contents($sRepURL); - preg_match_all('#([0-9]{3}/) *(([0-9]{2})-([A-z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}))#', $sRep, $aRepMatches, PREG_SET_ORDER); - $aPrevRepMatch = false; - foreach($aRepMatches as $aRepMatch) - { - if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break; - $aPrevRepMatch = $aRepMatch; - } - if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch; + // Find the last node in the DB + $iLastOSMID = $oDB->getOne("select max(id) from planet_osm_nodes"); + + // Lookup the timestamp that node was created (less 3 hours for margin for changsets to be closed) + $sLastNodeURL = 'http://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID."/1"; + $sLastNodeXML = file_get_contents($sLastNodeURL); + preg_match('#timestamp="(([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z)"#', $sLastNodeXML, $aLastNodeDate); + $iLastNodeTimestamp = strtotime($aLastNodeDate[1]) - (3*60*60); + + // Search for the correct state file - uses file timestamps so need to sort by date descending + $sRepURL = CONST_Replication_Url."/"; + $sRep = file_get_contents($sRepURL."?C=M;O=D"); + // download.geofabrik.de: 000/