4 require_once(dirname(dirname(__FILE__)).'/lib/init-cmd.php');
5 ini_set('memory_limit', '800M');
8 "Create and setup nominatim search system",
9 array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
10 array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
11 array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
13 array('all', '', 0, 1, 1, 1, 'realpath', 'Do the complete process'),
15 array('create-db', '', 0, 1, 0, 0, 'bool', 'Create nominatim db'),
16 array('setup-db', '', 0, 1, 0, 0, 'bool', 'Build a blank nominatim db'),
17 array('import-data', '', 0, 1, 1, 1, 'realpath', 'Import a osm file'),
18 array('create-functions', '', 0, 1, 0, 0, 'bool', 'Create functions'),
19 array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create main tables'),
20 array('create-partitions', '', 0, 1, 0, 0, 'bool', 'Create required partition tables and triggers'),
21 array('load-data', '', 0, 1, 0, 0, 'bool', 'Copy data to live tables from import table'),
23 getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
25 $bDidSomething = false;
27 if ($aCMDResult['create-db'] || isset($aCMDResult['all']))
29 $bDidSomething = true;
30 $oDB =& DB::connect(CONST_Database_DSN, false);
31 if (!PEAR::isError($oDB))
33 fail('database already exists');
35 passthru('createdb nominatim');
38 if ($aCMDResult['create-db'] || isset($aCMDResult['all']))
40 $bDidSomething = true;
41 // TODO: path detection, detection memory, etc.
44 passthru('createlang plpgsql nominatim');
45 pgsqlRunScriptFile(CONST_Path_Postgresql_Contrib.'/_int.sql');
46 pgsqlRunScriptFile(CONST_Path_Postgresql_Contrib.'/hstore.sql');
47 pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/postgis.sql');
48 pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/spatial_ref_sys.sql');
49 pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql');
50 pgsqlRunScriptFile(CONST_BasePath.'/data/country_naturaleathdata.sql');
51 pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql');
52 pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode.sql');
53 pgsqlRunScriptFile(CONST_BasePath.'/data/us_statecounty.sql');
54 pgsqlRunScriptFile(CONST_BasePath.'/data/us_state.sql');
55 pgsqlRunScriptFile(CONST_BasePath.'/data/worldboundaries.sql');
58 if (isset($aCMDResult['all']) && !isset($aCMDResult['import-data'])) $aCMDResult['import-data'] = $aCMDResult['all'];
59 if (isset($aCMDResult['import-data']) && $aCMDResult['import-data'])
61 $bDidSomething = true;
62 passthru(CONST_BasePath.'/osm2pgsql/osm2pgsql -lsc -O gazetteer -C 10000 --hstore -d nominatim '.$aCMDResult['import-data']);
65 if ($aCMDResult['create-functions'] || isset($aCMDResult['all']))
67 $bDidSomething = true;
68 $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
69 $sTemplate = str_replace('{modulepath}',CONST_BasePath.'/module', $sTemplate);
70 pgsqlRunScript($sTemplate);
73 if ($aCMDResult['create-tables'] || isset($aCMDResult['all']))
75 $bDidSomething = true;
76 pgsqlRunScriptFile(CONST_BasePath.'/sql/tables.sql');
78 // re-run the functions
79 $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
80 $sTemplate = str_replace('{modulepath}',CONST_BasePath.'/module', $sTemplate);
81 pgsqlRunScript($sTemplate);
84 if ($aCMDResult['create-partitions'] || isset($aCMDResult['all']))
86 $bDidSomething = true;
88 $sSQL = 'select partition from country_name order by country_code';
89 $aPartitions = $oDB->getCol($sSQL);
90 if (PEAR::isError($aPartitions))
92 fail($aPartitions->getMessage());
96 $sTemplate = file_get_contents(CONST_BasePath.'/sql/partitions.src.sql');
97 preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
98 foreach($aMatches as $aMatch)
101 foreach($aPartitions as $sPartitionName)
103 $sResult .= str_replace('-partition-', $sPartitionName, $aMatch[1]);
105 $sTemplate = str_replace($aMatch[0], $sResult, $sTemplate);
107 pgsqlRunScript($sTemplate);
110 if ($aCMDResult['load-data'] || isset($aCMDResult['all']))
112 $bDidSomething = true;
115 if (!pg_query($oDB->connection, 'TRUNCATE word')) fail(pg_last_error($oDB->connection));
117 if (!pg_query($oDB->connection, 'TRUNCATE placex')) fail(pg_last_error($oDB->connection));
119 if (!pg_query($oDB->connection, 'TRUNCATE place_addressline')) fail(pg_last_error($oDB->connection));
121 if (!pg_query($oDB->connection, 'TRUNCATE place_boundingbox')) fail(pg_last_error($oDB->connection));
123 if (!pg_query($oDB->connection, 'TRUNCATE location_area')) fail(pg_last_error($oDB->connection));
125 if (!pg_query($oDB->connection, 'TRUNCATE search_name')) fail(pg_last_error($oDB->connection));
127 if (!pg_query($oDB->connection, 'TRUNCATE search_name_blank')) fail(pg_last_error($oDB->connection));
129 if (!pg_query($oDB->connection, 'DROP SEQUENCE seq_place')) fail(pg_last_error($oDB->connection));
131 if (!pg_query($oDB->connection, 'CREATE SEQUENCE seq_place start 100000')) fail(pg_last_error($oDB->connection));
135 $aDBInstances = array();
136 for($i = 0; $i < $iInstances; $i++)
138 $aDBInstances[$i] =& getDB(true);
139 $sSQL = 'insert into placex (osm_type, osm_id, class, type, name, admin_level, ';
140 $sSQL .= 'housenumber, street, isin, postcode, country_code, extratags, ';
141 $sSQL .= 'geometry) select * from place where osm_id % '.$iInstances.' = '.$i;
143 if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
149 for($i = 0; $i < $iInstances; $i++)
151 if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
161 showUsage($aCMDOptions, true);
164 function pgsqlRunScriptFile($sFilename)
166 if (!file_exists($sFilename)) fail('unable to find '.$sFilename);
168 // Convert database DSN to psql paramaters
169 $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
170 $sCMD = 'psql -f '.$sFilename.' '.$aDSNInfo['database'];
172 $aDescriptors = array(
173 0 => array('pipe', 'r'),
174 1 => array('pipe', 'w'),
175 2 => array('file', '/dev/null', 'a')
178 $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
179 if (!is_resource($hProcess)) fail('unable to start pgsql');
183 // TODO: error checking
184 while(!feof($ahPipes[1]))
186 echo fread($ahPipes[1], 4096);
190 proc_close($hProcess);
193 function pgsqlRunScript($sScript)
195 // Convert database DSN to psql paramaters
196 $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
197 $sCMD = 'psql '.$aDSNInfo['database'];
199 $aDescriptors = array(
200 0 => array('pipe', 'r'),
201 1 => array('pipe', 'w'),
202 2 => array('file', '/dev/null', 'a')
205 $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
206 if (!is_resource($hProcess)) fail('unable to start pgsql');
208 fwrite($ahPipes[0], $sScript);
211 // TODO: error checking
212 while(!feof($ahPipes[1]))
214 echo fread($ahPipes[1], 4096);
218 proc_close($hProcess);