mirror of
https://github.com/osm-search/Nominatim.git
synced 2024-11-22 12:06:27 +03:00
nominatim refactoring
This commit is contained in:
commit
ab6a996772
145
lib/cmd.php
Normal file
145
lib/cmd.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
function getCmdOpt($aArg, $aSpec, &$aResult, $bExitOnError = false, $bExitOnUnknown = false)
|
||||
{
|
||||
$aQuick = array();
|
||||
$aCounts = array();
|
||||
|
||||
foreach($aSpec as $aLine)
|
||||
{
|
||||
if (is_array($aLine))
|
||||
{
|
||||
if ($aLine[0]) $aQuick['--'.$aLine[0]] = $aLine;
|
||||
if ($aLine[1]) $aQuick['-'.$aLine[1]] = $aLine;
|
||||
$aCounts[$aLine[0]] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$aResult = array();
|
||||
$bUnknown = false;
|
||||
$iSize = sizeof($aArg);
|
||||
for ($i = 1; $i < $iSize; $i++)
|
||||
{
|
||||
if (isset($aQuick[$aArg[$i]]))
|
||||
{
|
||||
$aLine = $aQuick[$aArg[$i]];
|
||||
$aCounts[$aLine[0]]++;
|
||||
$xVal = null;
|
||||
if ($aLine[4] == $aLine[5])
|
||||
{
|
||||
if ($aLine[4])
|
||||
{
|
||||
$xVal = array();
|
||||
for($n = $aLine[4]; $i < $iSize && $n; $n--)
|
||||
{
|
||||
$i++;
|
||||
if ($i >= $iSize || $aArg[$i][0] == '-') showUsage($aSpec, $bExitOnError, 'Parameter of \''.$aLine[0].'\' is missing');
|
||||
|
||||
switch ($aLine[6])
|
||||
{
|
||||
case 'realpath':
|
||||
$xVal[] = realpath($aArg[$i]);
|
||||
break;
|
||||
case 'realdir':
|
||||
$sPath = realpath(dirname($aArg[$i]));
|
||||
if ($sPath)
|
||||
$xVal[] = $sPath . '/' . basename($aArg[$i]);
|
||||
else
|
||||
$xVal[] = $sPath;
|
||||
break;
|
||||
case 'bool':
|
||||
$xVal[] = (bool)$aArg[$i];
|
||||
break;
|
||||
case 'int':
|
||||
$xVal[] = (int)$aArg[$i];
|
||||
break;
|
||||
case 'float':
|
||||
$xVal[] = (float)$aArg[$i];
|
||||
break;
|
||||
default:
|
||||
$xVal[] = $aArg[$i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($aLine[4] == 1) $xVal = $xVal[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$xVal = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fail('Variable numbers of params not yet supported');
|
||||
}
|
||||
|
||||
if ($aLine[3] > 1)
|
||||
{
|
||||
if (!array_key_exists($aLine[0], $aResult)) $aResult[$aLine[0]] = array();
|
||||
$aResult[$aLine[0]][] = $xVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[$aLine[0]] = $xVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bUnknown = $aArg[$i];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('help', $aResult)) showUsage($aSpec);
|
||||
if ($bUnknown && $bExitOnUnknown) showUsage($aSpec, $bExitOnError, 'Unknown option \''.$bUnknown.'\'');
|
||||
|
||||
foreach($aSpec as $aLine)
|
||||
{
|
||||
if (is_array($aLine))
|
||||
{
|
||||
if ($aCounts[$aLine[0]] < $aLine[2]) showUsage($aSpec, $bExitOnError, 'Option \''.$aLine[0].'\' is missing');
|
||||
if ($aCounts[$aLine[0]] > $aLine[3]) showUsage($aSpec, $bExitOnError, 'Option \''.$aLine[0].'\' is pressent too many times');
|
||||
switch ($aLine[6])
|
||||
{
|
||||
case 'bool':
|
||||
if (!array_key_exists($aLine[0], $aResult))
|
||||
$aResult[$aLine[0]] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $bUnknown;
|
||||
}
|
||||
|
||||
function showUsage($aSpec, $bExit = false, $sError = false)
|
||||
{
|
||||
if ($sError)
|
||||
{
|
||||
echo basename($_SERVER['argv'][0]).': '.$sError."\n";
|
||||
echo 'Try `'.basename($_SERVER['argv'][0]).' --help` for more information.'."\n";
|
||||
exit;
|
||||
}
|
||||
echo "Usage: ".basename($_SERVER['argv'][0])."\n";
|
||||
$bFirst = true;
|
||||
foreach($aSpec as $aLine)
|
||||
{
|
||||
if (is_array($aLine))
|
||||
{
|
||||
if ($bFirst)
|
||||
{
|
||||
$bFirst = false;
|
||||
echo "\n";
|
||||
}
|
||||
$aNames = array();
|
||||
if ($aLine[1]) $aNames[] = '-'.$aLine[1];
|
||||
if ($aLine[0]) $aNames[] = '--'.$aLine[0];
|
||||
$sName = join(', ',$aNames);
|
||||
echo ' '.$sName.str_repeat(' ',30-strlen($sName)).$aLine[7]."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $aLine."\n";
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
exit;
|
||||
}
|
18
lib/db.php
Normal file
18
lib/db.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
require_once('DB.php');
|
||||
|
||||
// Get the database object
|
||||
$oDB =& DB::connect(CONST_Database_DSN, false);
|
||||
if (PEAR::IsError($oDB))
|
||||
{
|
||||
fail($oDB->getMessage(), 'Unable to connect to the database');
|
||||
}
|
||||
$oDB->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||
$oDB->query("SET DateStyle TO 'sql,european'");
|
||||
$oDB->query("SET client_encoding TO 'utf-8'");
|
||||
|
||||
function getDBQuoted($s)
|
||||
{
|
||||
return "'".pg_escape_string($s)."'";
|
||||
}
|
||||
|
4
lib/init-cmd.php
Normal file
4
lib/init-cmd.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
require_once('init.php');
|
||||
require_once('cmd.php');
|
19
lib/init-website.php
Normal file
19
lib/init-website.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
require_once('init.php');
|
||||
|
||||
if (CONST_ClosedForIndexing && strpos(CONST_ClosedForIndexingExceptionIPs, ','.$_SERVER["REMOTE_ADDR"].',') === false)
|
||||
{
|
||||
echo "Closed for re-indexing...";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (strpos(CONST_BlockedIPs, ','.$_SERVER["REMOTE_ADDR"].',') !== false)
|
||||
{
|
||||
echo "Your IP has been blocked. \n";
|
||||
echo "Please create a nominatim trac ticket (http://trac.openstreetmap.org/newticket?component=nominatim) to request this to be removed. \n";
|
||||
echo "Information on the Nominatim usage policy can be found here: http://wiki.openstreetmap.org/wiki/Nominatim#Usage_Policy \n";
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-type: text/html; charset=utf-8');
|
13
lib/init.php
Normal file
13
lib/init.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
@define('CONST_BasePath', dirname(dirname(__FILE__)));
|
||||
|
||||
require_once(CONST_BasePath.'/settings/settings.php');
|
||||
require_once(CONST_BasePath.'/lib/lib.php');
|
||||
require_once(CONST_BasePath.'/lib/db.php');
|
||||
|
||||
if (get_magic_quotes_gpc())
|
||||
{
|
||||
echo "Please disable magic quotes in your php.ini configuration";
|
||||
exit;
|
||||
}
|
760
lib/lib.php
Normal file
760
lib/lib.php
Normal file
@ -0,0 +1,760 @@
|
||||
<?php
|
||||
|
||||
function fail($sError, $sUserError = false)
|
||||
{
|
||||
if (!$sUserError) $sUserError = $sError;
|
||||
log('ERROR:'.$sError);
|
||||
echo $sUserError;
|
||||
exit;
|
||||
}
|
||||
|
||||
function getBlockingProcesses()
|
||||
{
|
||||
$sStats = file_get_contents('/proc/stat');
|
||||
if (preg_match('/procs_blocked ([0-9]+)/i', $sStats, $aMatches))
|
||||
{
|
||||
return (int)$aMatches[1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getLoadAverage()
|
||||
{
|
||||
$sLoadAverage = file_get_contents('/proc/loadavg');
|
||||
$aLoadAverage = explode(' ',$sLoadAverage);
|
||||
return (int)$aLoadAverage[0];
|
||||
}
|
||||
|
||||
function bySearchRank($a, $b)
|
||||
{
|
||||
if ($a['iSearchRank'] == $b['iSearchRank']) return 0;
|
||||
return ($a['iSearchRank'] < $b['iSearchRank']?-1:1);
|
||||
}
|
||||
|
||||
function byImportance($a, $b)
|
||||
{
|
||||
if ($a['aPointPolygon']['numfeatures'] != $b['aPointPolygon']['numfeatures'])
|
||||
return ($a['aPointPolygon']['numfeatures'] > $b['aPointPolygon']['numfeatures']?-1:1);
|
||||
if ($a['aPointPolygon']['area'] != $b['aPointPolygon']['area'])
|
||||
return ($a['aPointPolygon']['area'] > $b['aPointPolygon']['area']?-1:1);
|
||||
if ($a['importance'] != $b['importance'])
|
||||
return ($a['importance'] < $b['importance']?-1:1);
|
||||
return ($a['foundorder'] < $b['foundorder']?-1:1);
|
||||
}
|
||||
|
||||
function getPrefferedLangauges()
|
||||
{
|
||||
// If we have been provided the value in $_GET it overrides browser value
|
||||
if (isset($_GET['accept-language']) && $_GET['accept-language'])
|
||||
{
|
||||
$_SERVER["HTTP_ACCEPT_LANGUAGE"] = $_GET['accept-language'];
|
||||
}
|
||||
|
||||
$aLanguages = array();
|
||||
if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $aLanguagesParse, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($aLanguagesParse as $iLang => $aLanguage)
|
||||
{
|
||||
$aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100);
|
||||
if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10;
|
||||
}
|
||||
arsort($aLanguages);
|
||||
}
|
||||
if (!sizeof($aLanguages)) $aLanguages = array(CONST_Default_Language=>1);
|
||||
foreach($aLanguages as $sLangauge => $fLangauagePref)
|
||||
{
|
||||
$aLangPrefOrder['short_name:'.$sLangauge] = 'short_name:'.$sLangauge;
|
||||
}
|
||||
foreach($aLanguages as $sLangauge => $fLangauagePref)
|
||||
{
|
||||
$aLangPrefOrder['name:'.$sLangauge] = 'name:'.$sLangauge;
|
||||
}
|
||||
foreach($aLanguages as $sLangauge => $fLangauagePref)
|
||||
{
|
||||
$aLangPrefOrder['place_name:'.$sLangauge] = 'place_name:'.$sLangauge;
|
||||
}
|
||||
foreach($aLanguages as $sLangauge => $fLangauagePref)
|
||||
{
|
||||
$aLangPrefOrder['official_name:'.$sLangauge] = 'official_name:'.$sLangauge;
|
||||
}
|
||||
$aLangPrefOrder['short_name'] = 'short_name';
|
||||
$aLangPrefOrder['name'] = 'name';
|
||||
$aLangPrefOrder['place_name'] = 'place_name';
|
||||
$aLangPrefOrder['official_name'] = 'official_name';
|
||||
$aLangPrefOrder['ref'] = 'ref';
|
||||
$aLangPrefOrder['type'] = 'type';
|
||||
return $aLangPrefOrder;
|
||||
}
|
||||
|
||||
function getWordSets($aWords)
|
||||
{
|
||||
$aResult = array(array(join(' ',$aWords)));
|
||||
$sFirstToken = '';
|
||||
while(sizeof($aWords) > 1)
|
||||
{
|
||||
$sWord = array_shift($aWords);
|
||||
$sFirstToken .= ($sFirstToken?' ':'').$sWord;
|
||||
$aRest = getWordSets($aWords);
|
||||
foreach($aRest as $aSet)
|
||||
{
|
||||
$aResult[] = array_merge(array($sFirstToken),$aSet);
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
function getTokensFromSets($aSets)
|
||||
{
|
||||
$aTokens = array();
|
||||
foreach($aSets as $aSet)
|
||||
{
|
||||
foreach($aSet as $sWord)
|
||||
{
|
||||
$aTokens[' '.$sWord] = ' '.$sWord;
|
||||
$aTokens[$sWord] = $sWord;
|
||||
//if (!strpos($sWord,' ')) $aTokens[$sWord] = $sWord;
|
||||
}
|
||||
}
|
||||
return $aTokens;
|
||||
}
|
||||
|
||||
/*
|
||||
GB Postcode functions
|
||||
*/
|
||||
|
||||
function gbPostcodeAlphaDifference($s1, $s2)
|
||||
{
|
||||
$aValues = array(
|
||||
'A'=>0,
|
||||
'B'=>1,
|
||||
'D'=>2,
|
||||
'E'=>3,
|
||||
'F'=>4,
|
||||
'G'=>5,
|
||||
'H'=>6,
|
||||
'J'=>7,
|
||||
'L'=>8,
|
||||
'N'=>9,
|
||||
'O'=>10,
|
||||
'P'=>11,
|
||||
'Q'=>12,
|
||||
'R'=>13,
|
||||
'S'=>14,
|
||||
'T'=>15,
|
||||
'U'=>16,
|
||||
'W'=>17,
|
||||
'X'=>18,
|
||||
'Y'=>19,
|
||||
'Z'=>20);
|
||||
return abs(($aValues[$s1[0]]*21+$aValues[$s1[1]]) - ($aValues[$s2[0]]*21+$aValues[$s2[1]]));
|
||||
}
|
||||
|
||||
function gbPostcodeCalculate($sPostcode, $sPostcodeSector, $sPostcodeEnd, &$oDB)
|
||||
{
|
||||
// Try an exact match on the gb_postcode table
|
||||
$sSQL = 'select \'AA\', ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from gb_postcode where upper(postcode) = \''.$sPostcode.'\'';
|
||||
$aNearPostcodes = $oDB->getAll($sSQL);
|
||||
if (PEAR::IsError($aNearPostcodes))
|
||||
{
|
||||
var_dump($sSQL, $aNearPostcodes);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!sizeof($aNearPostcodes))
|
||||
{
|
||||
$sSQL = 'select substring(upper(postcode) from \'^[A-Z][A-Z]?[0-9][0-9A-Z]? [0-9]([A-Z][A-Z])$\'),ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from placex where country_code::text = \'gb\'::text AND substring(upper(postcode) from \'^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])[A-Z][A-Z]$\') = \''.$sPostcodeSector.'\' and class=\'place\' and type=\'postcode\' ';
|
||||
$sSQL .= ' union ';
|
||||
$sSQL .= 'select substring(upper(postcode) from \'^[A-Z][A-Z]?[0-9][0-9A-Z]? [0-9]([A-Z][A-Z])$\'),ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from gb_postcode where substring(upper(postcode) from \'^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])[A-Z][A-Z]$\') = \''.$sPostcodeSector.'\'';
|
||||
$aNearPostcodes = $oDB->getAll($sSQL);
|
||||
if (PEAR::IsError($aNearPostcodes))
|
||||
{
|
||||
var_dump($sSQL, $aNearPostcodes);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizeof($aNearPostcodes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$fTotalLat = 0;
|
||||
$fTotalLon = 0;
|
||||
$fTotalFac = 0;
|
||||
foreach($aNearPostcodes as $aPostcode)
|
||||
{
|
||||
$iDiff = gbPostcodeAlphaDifference($sPostcodeEnd, $aPostcode['substring'])*2 + 1;
|
||||
if ($iDiff == 0)
|
||||
$fFac = 1;
|
||||
else
|
||||
$fFac = 1/($iDiff*$iDiff);
|
||||
|
||||
$fTotalFac += $fFac;
|
||||
$fTotalLat += $aPostcode['lat'] * $fFac;
|
||||
$fTotalLon += $aPostcode['lon'] * $fFac;
|
||||
}
|
||||
if ($fTotalFac)
|
||||
{
|
||||
$fLat = $fTotalLat / $fTotalFac;
|
||||
$fLon = $fTotalLon / $fTotalFac;
|
||||
$fRadius = min(0.1 / $fTotalFac, 0.02);
|
||||
return array(array('lat' => $fLat, 'lon' => $fLon, 'radius' => $fRadius));
|
||||
}
|
||||
return false;
|
||||
|
||||
/*
|
||||
$fTotalFac is a suprisingly good indicator of accuracy
|
||||
$iZoom = 18 + round(log($fTotalFac,32));
|
||||
$iZoom = max(13,min(18,$iZoom));
|
||||
*/
|
||||
}
|
||||
|
||||
function usPostcodeCalculate($sPostcode, &$oDB)
|
||||
{
|
||||
$iZipcode = (int)$sPostcode;
|
||||
|
||||
// Try an exact match on the us_zippostcode table
|
||||
$sSQL = 'select zipcode, ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from us_zipcode where zipcode = '.$iZipcode;
|
||||
$aNearPostcodes = $oDB->getAll($sSQL);
|
||||
if (PEAR::IsError($aNearPostcodes))
|
||||
{
|
||||
var_dump($sSQL, $aNearPostcodes);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!sizeof($aNearPostcodes))
|
||||
{
|
||||
$sSQL = 'select zipcode,ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from us_zipcode where zipcode between '.($iZipcode-100).' and '.($iZipcode+100).' order by abs(zipcode - '.$iZipcode.') asc limit 5';
|
||||
$aNearPostcodes = $oDB->getAll($sSQL);
|
||||
if (PEAR::IsError($aNearPostcodes))
|
||||
{
|
||||
var_dump($sSQL, $aNearPostcodes);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizeof($aNearPostcodes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$fTotalLat = 0;
|
||||
$fTotalLon = 0;
|
||||
$fTotalFac = 0;
|
||||
foreach($aNearPostcodes as $aPostcode)
|
||||
{
|
||||
$iDiff = abs($aPostcode['zipcode'] - $iZipcode) + 1;
|
||||
if ($iDiff == 0)
|
||||
$fFac = 1;
|
||||
else
|
||||
$fFac = 1/($iDiff*$iDiff);
|
||||
|
||||
$fTotalFac += $fFac;
|
||||
$fTotalLat += $aPostcode['lat'] * $fFac;
|
||||
$fTotalLon += $aPostcode['lon'] * $fFac;
|
||||
}
|
||||
if ($fTotalFac)
|
||||
{
|
||||
$fLat = $fTotalLat / $fTotalFac;
|
||||
$fLon = $fTotalLon / $fTotalFac;
|
||||
return array(array('lat' => $fLat, 'lon' => $fLon, 'radius' => 0.2));
|
||||
}
|
||||
return false;
|
||||
|
||||
/*
|
||||
$fTotalFac is a suprisingly good indicator of accuracy
|
||||
$iZoom = 18 + round(log($fTotalFac,32));
|
||||
$iZoom = max(13,min(18,$iZoom));
|
||||
*/
|
||||
}
|
||||
|
||||
function getClassTypes()
|
||||
{
|
||||
return array(
|
||||
'boundary:adminitrative:2' => array('label'=>'Country','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:4' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:5' => array('label'=>'State District','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:6' => array('label'=>'County','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:8' => array('label'=>'City','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:9' => array('label'=>'City District','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:10' => array('label'=>'Suburb','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'boundary:adminitrative:11' => array('label'=>'Neighbourhood','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'place:city' => array('label'=>'City','frequency'=>66,'icon'=>'poi_place_city','defzoom'=>12, 'defdiameter' => 0.32,),
|
||||
'place:country' => array('label'=>'Country','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>6, 'defdiameter' => 15,),
|
||||
'place:state' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>8, 'defdiameter' => 5.12,),
|
||||
'place:region' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>8, 'defdiameter' => 5.12,),
|
||||
'place:island' => array('label'=>'Island','frequency'=>288,'icon'=>'','defzoom'=>11, 'defdiameter' => 0.64,),
|
||||
'place:county' => array('label'=>'County','frequency'=>108,'icon'=>'poi_boundary_administrative','defzoom'=>10, 'defdiameter' => 1.28,),
|
||||
'boundary:adminitrative' => array('label'=>'Administrative','frequency'=>413,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
|
||||
'place:town' => array('label'=>'Town','frequency'=>1497,'icon'=>'poi_place_town','defzoom'=>14, 'defdiameter' => 0.08,),
|
||||
'place:village' => array('label'=>'Village','frequency'=>11230,'icon'=>'poi_place_village','defzoom'=>15, 'defdiameter' => 0.04,),
|
||||
'place:hamlet' => array('label'=>'Hamlet','frequency'=>7075,'icon'=>'poi_place_village','defzoom'=>15, 'defdiameter' => 0.04,),
|
||||
'place:suburb' => array('label'=>'Suburb','frequency'=>2528,'icon'=>'poi_place_village', 'defdiameter' => 0.04,),
|
||||
'place:locality' => array('label'=>'Locality','frequency'=>4113,'icon'=>'poi_place_village', 'defdiameter' => 0.02,),
|
||||
'landuse:farm' => array('label'=>'Farm','frequency'=>1201,'icon'=>'', 'defdiameter' => 0.02,),
|
||||
'place:farm' => array('label'=>'Farm','frequency'=>1162,'icon'=>'', 'defdiameter' => 0.02,),
|
||||
|
||||
'highway:motorway_junction' => array('label'=>'Motorway Junction','frequency'=>1126,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:motorway' => array('label'=>'Motorway','frequency'=>4627,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:trunk' => array('label'=>'Trunk','frequency'=>23084,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:primary' => array('label'=>'Primary','frequency'=>32138,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:secondary' => array('label'=>'Secondary','frequency'=>25807,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:tertiary' => array('label'=>'Tertiary','frequency'=>29829,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:residential' => array('label'=>'Residential','frequency'=>361498,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:unclassified' => array('label'=>'Unclassified','frequency'=>66441,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:living_street' => array('label'=>'Living Street','frequency'=>710,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:service' => array('label'=>'Service','frequency'=>9963,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:track' => array('label'=>'Track','frequency'=>2565,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:road' => array('label'=>'Road','frequency'=>591,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:byway' => array('label'=>'Byway','frequency'=>346,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:bridleway' => array('label'=>'Bridleway','frequency'=>1556,'icon'=>'',),
|
||||
'highway:cycleway' => array('label'=>'Cycleway','frequency'=>2419,'icon'=>'',),
|
||||
'highway:pedestrian' => array('label'=>'Pedestrian','frequency'=>2757,'icon'=>'',),
|
||||
'highway:footway' => array('label'=>'Footway','frequency'=>15008,'icon'=>'',),
|
||||
'highway:steps' => array('label'=>'Steps','frequency'=>444,'icon'=>'','simplelabel'=>'Footway',),
|
||||
'highway:motorway_link' => array('label'=>'Motorway Link','frequency'=>795,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:trunk_link' => array('label'=>'Trunk Link','frequency'=>1258,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:primary_link' => array('label'=>'Primary Link','frequency'=>313,'icon'=>'','simplelabel'=>'Road',),
|
||||
|
||||
'landuse:industrial' => array('label'=>'Industrial','frequency'=>1062,'icon'=>'',),
|
||||
'landuse:residential' => array('label'=>'Residential','frequency'=>886,'icon'=>'',),
|
||||
'landuse:retail' => array('label'=>'Retail','frequency'=>754,'icon'=>'',),
|
||||
'landuse:commercial' => array('label'=>'Commercial','frequency'=>657,'icon'=>'',),
|
||||
|
||||
'place:airport' => array('label'=>'Airport','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
|
||||
'railway:station' => array('label'=>'Station','frequency'=>3431,'icon'=>'transport_train_station2', 'defdiameter' => 0.01,),
|
||||
'amenity:place_of_worship' => array('label'=>'Place Of Worship','frequency'=>9049,'icon'=>'place_of_worship3',),
|
||||
'amenity:pub' => array('label'=>'Pub','frequency'=>18969,'icon'=>'food_pub',),
|
||||
'amenity:bar' => array('label'=>'Bar','frequency'=>164,'icon'=>'food_bar',),
|
||||
'amenity:university' => array('label'=>'University','frequency'=>607,'icon'=>'education_university',),
|
||||
'tourism:museum' => array('label'=>'Museum','frequency'=>543,'icon'=>'tourist_museum',),
|
||||
'amenity:arts_centre' => array('label'=>'Arts Centre','frequency'=>136,'icon'=>'tourist_art_gallery2',),
|
||||
'tourism:zoo' => array('label'=>'Zoo','frequency'=>47,'icon'=>'tourist_zoo',),
|
||||
'tourism:theme_park' => array('label'=>'Theme Park','frequency'=>24,'icon'=>'poi_point_of_interest',),
|
||||
'tourism:attraction' => array('label'=>'Attraction','frequency'=>1463,'icon'=>'poi_point_of_interest',),
|
||||
'leisure:golf_course' => array('label'=>'Golf Course','frequency'=>712,'icon'=>'sport_golf',),
|
||||
'historic:castle' => array('label'=>'Castle','frequency'=>316,'icon'=>'tourist_castle',),
|
||||
'amenity:hospital' => array('label'=>'Hospital','frequency'=>879,'icon'=>'health_hospital',),
|
||||
'amenity:school' => array('label'=>'School','frequency'=>8192,'icon'=>'education_school',),
|
||||
'amenity:theatre' => array('label'=>'Theatre','frequency'=>371,'icon'=>'tourist_theatre',),
|
||||
'amenity:public_building' => array('label'=>'Public Building','frequency'=>985,'icon'=>'',),
|
||||
'amenity:library' => array('label'=>'Library','frequency'=>794,'icon'=>'amenity_library',),
|
||||
'amenity:townhall' => array('label'=>'Townhall','frequency'=>242,'icon'=>'',),
|
||||
'amenity:community_centre' => array('label'=>'Community Centre','frequency'=>157,'icon'=>'',),
|
||||
'amenity:fire_station' => array('label'=>'Fire Station','frequency'=>221,'icon'=>'amenity_firestation3',),
|
||||
'amenity:police' => array('label'=>'Police','frequency'=>334,'icon'=>'amenity_police2',),
|
||||
'amenity:bank' => array('label'=>'Bank','frequency'=>1248,'icon'=>'money_bank2',),
|
||||
'amenity:post_office' => array('label'=>'Post Office','frequency'=>859,'icon'=>'amenity_post_office',),
|
||||
'leisure:park' => array('label'=>'Park','frequency'=>2378,'icon'=>'',),
|
||||
'amenity:park' => array('label'=>'Park','frequency'=>53,'icon'=>'',),
|
||||
'landuse:park' => array('label'=>'Park','frequency'=>50,'icon'=>'',),
|
||||
'landuse:recreation_ground' => array('label'=>'Recreation Ground','frequency'=>517,'icon'=>'',),
|
||||
'tourism:hotel' => array('label'=>'Hotel','frequency'=>2150,'icon'=>'accommodation_hotel2',),
|
||||
'tourism:motel' => array('label'=>'Motel','frequency'=>43,'icon'=>'',),
|
||||
'amenity:cinema' => array('label'=>'Cinema','frequency'=>277,'icon'=>'tourist_cinema',),
|
||||
'tourism:information' => array('label'=>'Information','frequency'=>224,'icon'=>'amenity_information',),
|
||||
'tourism:artwork' => array('label'=>'Artwork','frequency'=>171,'icon'=>'art_gallery2',),
|
||||
'historic:archaeological_site' => array('label'=>'Archaeological Site','frequency'=>407,'icon'=>'tourist_archaeological2',),
|
||||
'amenity:doctors' => array('label'=>'Doctors','frequency'=>581,'icon'=>'health_doctors',),
|
||||
'leisure:sports_centre' => array('label'=>'Sports Centre','frequency'=>767,'icon'=>'sport_leisure_centre',),
|
||||
'leisure:swimming_pool' => array('label'=>'Swimming Pool','frequency'=>24,'icon'=>'sport_swimming_outdoor',),
|
||||
'shop:supermarket' => array('label'=>'Supermarket','frequency'=>2673,'icon'=>'shopping_supermarket',),
|
||||
'shop:convenience' => array('label'=>'Convenience','frequency'=>1469,'icon'=>'shopping_convenience',),
|
||||
'amenity:restaurant' => array('label'=>'Restaurant','frequency'=>3179,'icon'=>'food_restaurant',),
|
||||
'amenity:fast_food' => array('label'=>'Fast Food','frequency'=>2289,'icon'=>'food_fastfood',),
|
||||
'amenity:cafe' => array('label'=>'Cafe','frequency'=>1780,'icon'=>'food_cafe',),
|
||||
'tourism:guest_house' => array('label'=>'Guest House','frequency'=>223,'icon'=>'accommodation_bed_and_breakfast',),
|
||||
'amenity:pharmacy' => array('label'=>'Pharmacy','frequency'=>733,'icon'=>'health_pharmacy_dispensing',),
|
||||
'amenity:fuel' => array('label'=>'Fuel','frequency'=>1308,'icon'=>'transport_fuel',),
|
||||
'natural:peak' => array('label'=>'Peak','frequency'=>3212,'icon'=>'poi_peak',),
|
||||
'waterway:waterfall' => array('label'=>'Waterfall','frequency'=>24,'icon'=>'',),
|
||||
'natural:wood' => array('label'=>'Wood','frequency'=>1845,'icon'=>'landuse_coniferous_and_deciduous',),
|
||||
'natural:water' => array('label'=>'Water','frequency'=>1790,'icon'=>'',),
|
||||
'landuse:forest' => array('label'=>'Forest','frequency'=>467,'icon'=>'',),
|
||||
'landuse:cemetery' => array('label'=>'Cemetery','frequency'=>463,'icon'=>'',),
|
||||
'landuse:allotments' => array('label'=>'Allotments','frequency'=>408,'icon'=>'',),
|
||||
'landuse:farmyard' => array('label'=>'Farmyard','frequency'=>397,'icon'=>'',),
|
||||
'railway:rail' => array('label'=>'Rail','frequency'=>4894,'icon'=>'',),
|
||||
'waterway:canal' => array('label'=>'Canal','frequency'=>1723,'icon'=>'',),
|
||||
'waterway:river' => array('label'=>'River','frequency'=>4089,'icon'=>'',),
|
||||
'waterway:stream' => array('label'=>'Stream','frequency'=>2684,'icon'=>'',),
|
||||
'shop:bicycle' => array('label'=>'Bicycle','frequency'=>349,'icon'=>'shopping_bicycle',),
|
||||
'shop:clothes' => array('label'=>'Clothes','frequency'=>315,'icon'=>'shopping_clothes',),
|
||||
'shop:hairdresser' => array('label'=>'Hairdresser','frequency'=>312,'icon'=>'shopping_hairdresser',),
|
||||
'shop:doityourself' => array('label'=>'Doityourself','frequency'=>247,'icon'=>'shopping_diy',),
|
||||
'shop:estate_agent' => array('label'=>'Estate Agent','frequency'=>162,'icon'=>'shopping_estateagent2',),
|
||||
'shop:car' => array('label'=>'Car','frequency'=>159,'icon'=>'shopping_car',),
|
||||
'shop:garden_centre' => array('label'=>'Garden Centre','frequency'=>143,'icon'=>'shopping_garden_centre',),
|
||||
'shop:car_repair' => array('label'=>'Car Repair','frequency'=>141,'icon'=>'shopping_car_repair',),
|
||||
'shop:newsagent' => array('label'=>'Newsagent','frequency'=>132,'icon'=>'',),
|
||||
'shop:bakery' => array('label'=>'Bakery','frequency'=>129,'icon'=>'shopping_bakery',),
|
||||
'shop:furniture' => array('label'=>'Furniture','frequency'=>124,'icon'=>'',),
|
||||
'shop:butcher' => array('label'=>'Butcher','frequency'=>105,'icon'=>'shopping_butcher',),
|
||||
'shop:apparel' => array('label'=>'Apparel','frequency'=>98,'icon'=>'shopping_clothes',),
|
||||
'shop:electronics' => array('label'=>'Electronics','frequency'=>96,'icon'=>'',),
|
||||
'shop:department_store' => array('label'=>'Department Store','frequency'=>86,'icon'=>'',),
|
||||
'shop:books' => array('label'=>'Books','frequency'=>85,'icon'=>'',),
|
||||
'shop:yes' => array('label'=>'Yes','frequency'=>68,'icon'=>'',),
|
||||
'shop:outdoor' => array('label'=>'Outdoor','frequency'=>67,'icon'=>'',),
|
||||
'shop:mall' => array('label'=>'Mall','frequency'=>63,'icon'=>'',),
|
||||
'shop:florist' => array('label'=>'Florist','frequency'=>61,'icon'=>'',),
|
||||
'shop:charity' => array('label'=>'Charity','frequency'=>60,'icon'=>'',),
|
||||
'shop:hardware' => array('label'=>'Hardware','frequency'=>59,'icon'=>'',),
|
||||
'shop:laundry' => array('label'=>'Laundry','frequency'=>51,'icon'=>'shopping_laundrette',),
|
||||
'shop:shoes' => array('label'=>'Shoes','frequency'=>49,'icon'=>'',),
|
||||
'shop:beverages' => array('label'=>'Beverages','frequency'=>48,'icon'=>'shopping_alcohol',),
|
||||
'shop:dry_cleaning' => array('label'=>'Dry Cleaning','frequency'=>46,'icon'=>'',),
|
||||
'shop:carpet' => array('label'=>'Carpet','frequency'=>45,'icon'=>'',),
|
||||
'shop:computer' => array('label'=>'Computer','frequency'=>44,'icon'=>'',),
|
||||
'shop:alcohol' => array('label'=>'Alcohol','frequency'=>44,'icon'=>'shopping_alcohol',),
|
||||
'shop:optician' => array('label'=>'Optician','frequency'=>55,'icon'=>'health_opticians',),
|
||||
'shop:chemist' => array('label'=>'Chemist','frequency'=>42,'icon'=>'health_pharmacy',),
|
||||
'shop:gallery' => array('label'=>'Gallery','frequency'=>38,'icon'=>'tourist_art_gallery2',),
|
||||
'shop:mobile_phone' => array('label'=>'Mobile Phone','frequency'=>37,'icon'=>'',),
|
||||
'shop:sports' => array('label'=>'Sports','frequency'=>37,'icon'=>'',),
|
||||
'shop:jewelry' => array('label'=>'Jewelry','frequency'=>32,'icon'=>'shopping_jewelry',),
|
||||
'shop:pet' => array('label'=>'Pet','frequency'=>29,'icon'=>'',),
|
||||
'shop:beauty' => array('label'=>'Beauty','frequency'=>28,'icon'=>'',),
|
||||
'shop:stationery' => array('label'=>'Stationery','frequency'=>25,'icon'=>'',),
|
||||
'shop:shopping_centre' => array('label'=>'Shopping Centre','frequency'=>25,'icon'=>'',),
|
||||
'shop:general' => array('label'=>'General','frequency'=>25,'icon'=>'',),
|
||||
'shop:electrical' => array('label'=>'Electrical','frequency'=>25,'icon'=>'',),
|
||||
'shop:toys' => array('label'=>'Toys','frequency'=>23,'icon'=>'',),
|
||||
'shop:jeweller' => array('label'=>'Jeweller','frequency'=>23,'icon'=>'',),
|
||||
'shop:betting' => array('label'=>'Betting','frequency'=>23,'icon'=>'',),
|
||||
'shop:household' => array('label'=>'Household','frequency'=>21,'icon'=>'',),
|
||||
'shop:travel_agency' => array('label'=>'Travel Agency','frequency'=>21,'icon'=>'',),
|
||||
'shop:hifi' => array('label'=>'Hifi','frequency'=>21,'icon'=>'',),
|
||||
'amenity:shop' => array('label'=>'Shop','frequency'=>61,'icon'=>'',),
|
||||
|
||||
'place:house' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
|
||||
|
||||
//
|
||||
|
||||
'leisure:pitch' => array('label'=>'Pitch','frequency'=>762,'icon'=>'',),
|
||||
'highway:unsurfaced' => array('label'=>'Unsurfaced','frequency'=>492,'icon'=>'',),
|
||||
'historic:ruins' => array('label'=>'Ruins','frequency'=>483,'icon'=>'shopping_jewelry',),
|
||||
'amenity:college' => array('label'=>'College','frequency'=>473,'icon'=>'education_school',),
|
||||
'historic:monument' => array('label'=>'Monument','frequency'=>470,'icon'=>'tourist_monument',),
|
||||
'railway:subway' => array('label'=>'Subway','frequency'=>385,'icon'=>'',),
|
||||
'historic:memorial' => array('label'=>'Memorial','frequency'=>382,'icon'=>'tourist_monument',),
|
||||
'leisure:nature_reserve' => array('label'=>'Nature Reserve','frequency'=>342,'icon'=>'',),
|
||||
'leisure:common' => array('label'=>'Common','frequency'=>322,'icon'=>'',),
|
||||
'waterway:lock_gate' => array('label'=>'Lock Gate','frequency'=>321,'icon'=>'',),
|
||||
'natural:fell' => array('label'=>'Fell','frequency'=>308,'icon'=>'',),
|
||||
'amenity:nightclub' => array('label'=>'Nightclub','frequency'=>292,'icon'=>'',),
|
||||
'highway:path' => array('label'=>'Path','frequency'=>287,'icon'=>'',),
|
||||
'leisure:garden' => array('label'=>'Garden','frequency'=>285,'icon'=>'',),
|
||||
'landuse:reservoir' => array('label'=>'Reservoir','frequency'=>276,'icon'=>'',),
|
||||
'leisure:playground' => array('label'=>'Playground','frequency'=>264,'icon'=>'',),
|
||||
'leisure:stadium' => array('label'=>'Stadium','frequency'=>212,'icon'=>'',),
|
||||
'historic:mine' => array('label'=>'Mine','frequency'=>193,'icon'=>'poi_mine',),
|
||||
'natural:cliff' => array('label'=>'Cliff','frequency'=>193,'icon'=>'',),
|
||||
'tourism:caravan_site' => array('label'=>'Caravan Site','frequency'=>183,'icon'=>'accommodation_caravan_park',),
|
||||
'amenity:bus_station' => array('label'=>'Bus Station','frequency'=>181,'icon'=>'transport_bus_station',),
|
||||
'amenity:kindergarten' => array('label'=>'Kindergarten','frequency'=>179,'icon'=>'',),
|
||||
'highway:construction' => array('label'=>'Construction','frequency'=>176,'icon'=>'',),
|
||||
'amenity:atm' => array('label'=>'Atm','frequency'=>172,'icon'=>'money_atm2',),
|
||||
'amenity:emergency_phone' => array('label'=>'Emergency Phone','frequency'=>164,'icon'=>'',),
|
||||
'waterway:lock' => array('label'=>'Lock','frequency'=>146,'icon'=>'',),
|
||||
'waterway:riverbank' => array('label'=>'Riverbank','frequency'=>143,'icon'=>'',),
|
||||
'natural:coastline' => array('label'=>'Coastline','frequency'=>142,'icon'=>'',),
|
||||
'tourism:viewpoint' => array('label'=>'Viewpoint','frequency'=>140,'icon'=>'tourist_view_point',),
|
||||
'tourism:hostel' => array('label'=>'Hostel','frequency'=>140,'icon'=>'',),
|
||||
'tourism:bed_and_breakfast' => array('label'=>'Bed And Breakfast','frequency'=>140,'icon'=>'accommodation_bed_and_breakfast',),
|
||||
'railway:halt' => array('label'=>'Halt','frequency'=>135,'icon'=>'',),
|
||||
'railway:platform' => array('label'=>'Platform','frequency'=>134,'icon'=>'',),
|
||||
'railway:tram' => array('label'=>'Tram','frequency'=>130,'icon'=>'transport_tram_stop',),
|
||||
'amenity:courthouse' => array('label'=>'Courthouse','frequency'=>129,'icon'=>'amenity_court',),
|
||||
'amenity:recycling' => array('label'=>'Recycling','frequency'=>126,'icon'=>'amenity_recycling',),
|
||||
'amenity:dentist' => array('label'=>'Dentist','frequency'=>124,'icon'=>'health_dentist',),
|
||||
'natural:beach' => array('label'=>'Beach','frequency'=>121,'icon'=>'tourist_beach',),
|
||||
'place:moor' => array('label'=>'Moor','frequency'=>118,'icon'=>'',),
|
||||
'amenity:grave_yard' => array('label'=>'Grave Yard','frequency'=>110,'icon'=>'',),
|
||||
'waterway:derelict_canal' => array('label'=>'Derelict Canal','frequency'=>109,'icon'=>'',),
|
||||
'waterway:drain' => array('label'=>'Drain','frequency'=>108,'icon'=>'',),
|
||||
'landuse:grass' => array('label'=>'Grass','frequency'=>106,'icon'=>'',),
|
||||
'landuse:village_green' => array('label'=>'Village Green','frequency'=>106,'icon'=>'',),
|
||||
'natural:bay' => array('label'=>'Bay','frequency'=>102,'icon'=>'',),
|
||||
'railway:tram_stop' => array('label'=>'Tram Stop','frequency'=>101,'icon'=>'transport_tram_stop',),
|
||||
'leisure:marina' => array('label'=>'Marina','frequency'=>98,'icon'=>'',),
|
||||
'highway:stile' => array('label'=>'Stile','frequency'=>97,'icon'=>'',),
|
||||
'natural:moor' => array('label'=>'Moor','frequency'=>95,'icon'=>'',),
|
||||
'railway:light_rail' => array('label'=>'Light Rail','frequency'=>91,'icon'=>'',),
|
||||
'railway:narrow_gauge' => array('label'=>'Narrow Gauge','frequency'=>90,'icon'=>'',),
|
||||
'natural:land' => array('label'=>'Land','frequency'=>86,'icon'=>'',),
|
||||
'amenity:village_hall' => array('label'=>'Village Hall','frequency'=>82,'icon'=>'',),
|
||||
'waterway:dock' => array('label'=>'Dock','frequency'=>80,'icon'=>'',),
|
||||
'amenity:veterinary' => array('label'=>'Veterinary','frequency'=>79,'icon'=>'',),
|
||||
'landuse:brownfield' => array('label'=>'Brownfield','frequency'=>77,'icon'=>'',),
|
||||
'leisure:track' => array('label'=>'Track','frequency'=>76,'icon'=>'',),
|
||||
'railway:historic_station' => array('label'=>'Historic Station','frequency'=>74,'icon'=>'',),
|
||||
'landuse:construction' => array('label'=>'Construction','frequency'=>72,'icon'=>'',),
|
||||
'amenity:prison' => array('label'=>'Prison','frequency'=>71,'icon'=>'amenity_prison',),
|
||||
'landuse:quarry' => array('label'=>'Quarry','frequency'=>71,'icon'=>'',),
|
||||
'amenity:telephone' => array('label'=>'Telephone','frequency'=>70,'icon'=>'',),
|
||||
'highway:traffic_signals' => array('label'=>'Traffic Signals','frequency'=>66,'icon'=>'',),
|
||||
'natural:heath' => array('label'=>'Heath','frequency'=>62,'icon'=>'',),
|
||||
'historic:house' => array('label'=>'House','frequency'=>61,'icon'=>'',),
|
||||
'amenity:social_club' => array('label'=>'Social Club','frequency'=>61,'icon'=>'',),
|
||||
'landuse:military' => array('label'=>'Military','frequency'=>61,'icon'=>'',),
|
||||
'amenity:health_centre' => array('label'=>'Health Centre','frequency'=>59,'icon'=>'',),
|
||||
'historic:building' => array('label'=>'Building','frequency'=>58,'icon'=>'',),
|
||||
'amenity:clinic' => array('label'=>'Clinic','frequency'=>57,'icon'=>'',),
|
||||
'highway:services' => array('label'=>'Services','frequency'=>56,'icon'=>'',),
|
||||
'amenity:ferry_terminal' => array('label'=>'Ferry Terminal','frequency'=>55,'icon'=>'',),
|
||||
'natural:marsh' => array('label'=>'Marsh','frequency'=>55,'icon'=>'',),
|
||||
'natural:hill' => array('label'=>'Hill','frequency'=>54,'icon'=>'',),
|
||||
'highway:raceway' => array('label'=>'Raceway','frequency'=>53,'icon'=>'',),
|
||||
'amenity:taxi' => array('label'=>'Taxi','frequency'=>47,'icon'=>'',),
|
||||
'amenity:take_away' => array('label'=>'Take Away','frequency'=>45,'icon'=>'',),
|
||||
'amenity:car_rental' => array('label'=>'Car Rental','frequency'=>44,'icon'=>'',),
|
||||
'place:islet' => array('label'=>'Islet','frequency'=>44,'icon'=>'',),
|
||||
'amenity:nursery' => array('label'=>'Nursery','frequency'=>44,'icon'=>'',),
|
||||
'amenity:nursing_home' => array('label'=>'Nursing Home','frequency'=>43,'icon'=>'',),
|
||||
'amenity:toilets' => array('label'=>'Toilets','frequency'=>38,'icon'=>'',),
|
||||
'amenity:hall' => array('label'=>'Hall','frequency'=>38,'icon'=>'',),
|
||||
'waterway:boatyard' => array('label'=>'Boatyard','frequency'=>36,'icon'=>'',),
|
||||
'highway:mini_roundabout' => array('label'=>'Mini Roundabout','frequency'=>35,'icon'=>'',),
|
||||
'historic:manor' => array('label'=>'Manor','frequency'=>35,'icon'=>'',),
|
||||
'tourism:chalet' => array('label'=>'Chalet','frequency'=>34,'icon'=>'',),
|
||||
'amenity:bicycle_parking' => array('label'=>'Bicycle Parking','frequency'=>34,'icon'=>'',),
|
||||
'amenity:hotel' => array('label'=>'Hotel','frequency'=>34,'icon'=>'',),
|
||||
'waterway:weir' => array('label'=>'Weir','frequency'=>33,'icon'=>'',),
|
||||
'natural:wetland' => array('label'=>'Wetland','frequency'=>33,'icon'=>'',),
|
||||
'natural:cave_entrance' => array('label'=>'Cave Entrance','frequency'=>32,'icon'=>'',),
|
||||
'amenity:crematorium' => array('label'=>'Crematorium','frequency'=>31,'icon'=>'',),
|
||||
'tourism:picnic_site' => array('label'=>'Picnic Site','frequency'=>31,'icon'=>'',),
|
||||
'landuse:wood' => array('label'=>'Wood','frequency'=>30,'icon'=>'',),
|
||||
'landuse:basin' => array('label'=>'Basin','frequency'=>30,'icon'=>'',),
|
||||
'natural:tree' => array('label'=>'Tree','frequency'=>30,'icon'=>'',),
|
||||
'leisure:slipway' => array('label'=>'Slipway','frequency'=>29,'icon'=>'',),
|
||||
'landuse:meadow' => array('label'=>'Meadow','frequency'=>29,'icon'=>'',),
|
||||
'landuse:piste' => array('label'=>'Piste','frequency'=>28,'icon'=>'',),
|
||||
'amenity:care_home' => array('label'=>'Care Home','frequency'=>28,'icon'=>'',),
|
||||
'amenity:club' => array('label'=>'Club','frequency'=>28,'icon'=>'',),
|
||||
'amenity:medical_centre' => array('label'=>'Medical Centre','frequency'=>27,'icon'=>'',),
|
||||
'historic:roman_road' => array('label'=>'Roman Road','frequency'=>27,'icon'=>'',),
|
||||
'historic:fort' => array('label'=>'Fort','frequency'=>26,'icon'=>'',),
|
||||
'railway:subway_entrance' => array('label'=>'Subway Entrance','frequency'=>26,'icon'=>'',),
|
||||
'historic:yes' => array('label'=>'Yes','frequency'=>25,'icon'=>'',),
|
||||
'highway:gate' => array('label'=>'Gate','frequency'=>25,'icon'=>'',),
|
||||
'leisure:fishing' => array('label'=>'Fishing','frequency'=>24,'icon'=>'',),
|
||||
'historic:museum' => array('label'=>'Museum','frequency'=>24,'icon'=>'',),
|
||||
'amenity:car_wash' => array('label'=>'Car Wash','frequency'=>24,'icon'=>'',),
|
||||
'railway:level_crossing' => array('label'=>'Level Crossing','frequency'=>23,'icon'=>'',),
|
||||
'leisure:bird_hide' => array('label'=>'Bird Hide','frequency'=>23,'icon'=>'',),
|
||||
'natural:headland' => array('label'=>'Headland','frequency'=>21,'icon'=>'',),
|
||||
'tourism:apartments' => array('label'=>'Apartments','frequency'=>21,'icon'=>'',),
|
||||
'amenity:shopping' => array('label'=>'Shopping','frequency'=>21,'icon'=>'',),
|
||||
'natural:scrub' => array('label'=>'Scrub','frequency'=>20,'icon'=>'',),
|
||||
'natural:fen' => array('label'=>'Fen','frequency'=>20,'icon'=>'',),
|
||||
|
||||
'amenity:parking' => array('label'=>'Parking','frequency'=>3157,'icon'=>'',),
|
||||
'highway:bus_stop' => array('label'=>'Bus Stop','frequency'=>35777,'icon'=>'transport_bus_stop2',),
|
||||
'place:postcode' => array('label'=>'Postcode','frequency'=>27267,'icon'=>'',),
|
||||
'amenity:post_box' => array('label'=>'Post Box','frequency'=>9613,'icon'=>'',),
|
||||
|
||||
'place:houses' => array('label'=>'Houses','frequency'=>85,'icon'=>'',),
|
||||
'railway:preserved' => array('label'=>'Preserved','frequency'=>227,'icon'=>'',),
|
||||
'waterway:derelict canal' => array('label'=>'Derelict Canal','frequency'=>21,'icon'=>'',),
|
||||
'amenity:dead_pub' => array('label'=>'Dead Pub','frequency'=>20,'icon'=>'',),
|
||||
'railway:disused_station' => array('label'=>'Disused Station','frequency'=>114,'icon'=>'',),
|
||||
'railway:abandoned' => array('label'=>'Abandoned','frequency'=>641,'icon'=>'',),
|
||||
'railway:disused' => array('label'=>'Disused','frequency'=>72,'icon'=>'',),
|
||||
);
|
||||
}
|
||||
|
||||
function getClassTypesWithImportance()
|
||||
{
|
||||
$aOrders = getClassTypes();
|
||||
$i = 1;
|
||||
foreach($aOrders as $sID => $a)
|
||||
{
|
||||
$aOrders[$sID]['importance'] = $i++;
|
||||
}
|
||||
return $aOrders;
|
||||
}
|
||||
|
||||
|
||||
function javascript_isarray($xVal)
|
||||
{
|
||||
if (!is_array($xVal)) return false;
|
||||
for($i = 0; $i < sizeof($xVal); $i++)
|
||||
{
|
||||
if (!array_key_exists($i, $xVal)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function javascript_renderData($xVal, $bForceHash = false)
|
||||
{
|
||||
if (is_array($xVal))
|
||||
{
|
||||
$aVals = array();
|
||||
if (javascript_isarray($xVal) && !$bForceHash)
|
||||
{
|
||||
foreach($xVal as $sKey => $xData)
|
||||
{
|
||||
$aVals[] = javascript_renderData($xData);
|
||||
}
|
||||
return '['.join(',',$aVals).']';
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($xVal as $sKey => $xData)
|
||||
{
|
||||
$aVals[] = '"'.addslashes($sKey).'"'.':'.javascript_renderData($xData);
|
||||
}
|
||||
return '{'.join(',',$aVals).'}';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_bool($xVal)) return $xVal?'true':'false';
|
||||
if (is_numeric($xVal)) return $xVal;
|
||||
return '"'.str_replace('>','\\>',str_replace(array("\n","\r"),'\\n',str_replace(array("\n\r","\r\n"),'\\n',str_replace('"','\\"',$xVal)))).'"';
|
||||
}
|
||||
}
|
||||
|
||||
function _debugDumpGroupedSearches($aData, $aTokens)
|
||||
{
|
||||
$aWordsIDs = array();
|
||||
foreach($aTokens as $sToken => $aWords)
|
||||
{
|
||||
foreach($aWords as $aToken)
|
||||
{
|
||||
$aWordsIDs[$aToken['word_id']] = $sToken.'('.$aToken['word_id'].')';
|
||||
}
|
||||
}
|
||||
echo "<table border=\"1\">";
|
||||
echo "<tr><th>rank</th><th>Name Tokens</th><th>Address Tokens</th><th>country</th><th>operator</th><th>class</th><th>type</th><th>house#</th><th>Lat</th><th>Lon</th><th>Radius</th></tr>";
|
||||
foreach($aData as $iRank => $aRankedSet)
|
||||
{
|
||||
foreach($aRankedSet as $aRow)
|
||||
{
|
||||
echo "<tr>";
|
||||
echo "<td>$iRank</td>";
|
||||
|
||||
echo "<td>";
|
||||
$sSep = '';
|
||||
foreach($aRow['aName'] as $iWordID)
|
||||
{
|
||||
echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
|
||||
$sSep = ', ';
|
||||
}
|
||||
echo "</td>";
|
||||
|
||||
echo "<td>";
|
||||
$sSep = '';
|
||||
foreach($aRow['aAddress'] as $iWordID)
|
||||
{
|
||||
// if (!isset($aRow['aName'][$iWordID]))
|
||||
{
|
||||
echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
|
||||
$sSep = ', ';
|
||||
}
|
||||
}
|
||||
echo "</td>";
|
||||
|
||||
echo "<td>".$aRow['sCountryCode']."</td>";
|
||||
|
||||
echo "<td>".$aRow['sOperator']."</td>";
|
||||
echo "<td>".$aRow['sClass']."</td>";
|
||||
echo "<td>".$aRow['sType']."</td>";
|
||||
|
||||
echo "<td>".$aRow['sHouseNumber']."</td>";
|
||||
|
||||
echo "<td>".$aRow['fLat']."</td>";
|
||||
echo "<td>".$aRow['fLon']."</td>";
|
||||
echo "<td>".$aRow['fRadius']."</td>";
|
||||
|
||||
echo "</tr>";
|
||||
}
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
|
||||
function getAddressDetails(&$oDB, $sLanguagePrefArraySQL, $iPlaceID, $sCountryCode = false, $bRaw = false)
|
||||
{
|
||||
$aHouseNumber = $oDB->getRow('select housenumber, get_name_by_language(name,ARRAY[\'addr:housename\']) as housename,rank_search from placex where place_id = '.$iPlaceID);
|
||||
$sHouseNumber = $aHouseNumber['housenumber'];
|
||||
$sHouseName = $aHouseNumber['housename'];
|
||||
$iRank = $aHouseNumber['rank_search'];
|
||||
|
||||
// Address
|
||||
$sSQL = "select country_code, placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, ";
|
||||
$sSQL .= "get_searchrank_label(rank_search) as rank_search_label, fromarea, isaddress, distance, ";
|
||||
$sSQL .= " CASE WHEN type = 'postcode' THEN postcode ELSE get_name_by_language(name,$sLanguagePrefArraySQL) END as localname, ";
|
||||
$sSQL .= " length(name::text) as namelength ";
|
||||
$sSQL .= " from place_addressline join placex on (address_place_id = placex.place_id)";
|
||||
$sSQL .= " where place_addressline.place_id = $iPlaceID and (rank_address > 0 OR address_place_id = $iPlaceID)";
|
||||
// and isaddress";
|
||||
if ($sCountryCode)
|
||||
{
|
||||
$sSQL .= " and (placex.country_code IS NULL OR placex.country_code = '".$sCountryCode."' OR rank_address < 4)";
|
||||
}
|
||||
$sSQL .= " order by cached_rank_address desc,fromarea desc,distance asc,rank_search desc,namelength desc";
|
||||
//var_dump($sSQL);
|
||||
$aAddressLines = $oDB->getAll($sSQL);
|
||||
if (PEAR::IsError($aAddressLines))
|
||||
{
|
||||
var_dump($aAddressLines);
|
||||
exit;
|
||||
}
|
||||
if ($bRaw) return $aAddressLines;
|
||||
|
||||
$aClassType = getClassTypes();
|
||||
|
||||
$iMinRank = 100;
|
||||
$aAddress = array();
|
||||
if ($iRank >= 28 && $sHouseNumber) $aAddress['house_number'] = $sHouseNumber;
|
||||
if ($iRank >= 28 && $sHouseName) $aAddress['house_name'] = $sHouseName;
|
||||
foreach($aAddressLines as $aLine)
|
||||
{
|
||||
if (!$sCountryCode) $sCountryCode = $aLine['country_code'];
|
||||
if ($aLine['rank_address'] < $iMinRank)
|
||||
{
|
||||
$aTypeLabel = false;
|
||||
if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
|
||||
elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
|
||||
else $aTypeLabel = array('simplelabel'=>$aLine['class']);
|
||||
if ($aTypeLabel && ($aLine['localname'] || $aLine['housenumber']))
|
||||
{
|
||||
$sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
|
||||
if (!isset($aAddress[$sTypeLabel]) && $aLine['localname']) $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
|
||||
}
|
||||
$iMinRank = $aLine['rank_address'];
|
||||
}
|
||||
}
|
||||
if ($iMinRank > 4 && $sCountryCode)
|
||||
{
|
||||
$sSQL = "select get_name_by_language(country_name.name,$sLanguagePrefArraySQL) as name";
|
||||
$sSQL .= " from country_name where country_code = '$sCountryCode'";
|
||||
$sCountryName = $oDB->getOne($sSQL);
|
||||
if ($sCountryName)
|
||||
{
|
||||
$aAddress['country'] = $sCountryName;
|
||||
}
|
||||
}
|
||||
if ($sCountryCode)
|
||||
{
|
||||
$aAddress['country_code'] = $sCountryCode;
|
||||
}
|
||||
|
||||
return $aAddress;
|
||||
}
|
||||
|
||||
function getWordSuggestions(&$oDB, $sWord)
|
||||
{
|
||||
$sWordQuoted = getDBQuoted(trim($sWord));
|
||||
$sSQL = "select *,levenshtein($sWordQuoted,word) from test_token ";
|
||||
$sSQL .= "where (metaphone = dmetaphone($sWordQuoted) or metaphonealt = dmetaphone($sWordQuoted) or ";
|
||||
$sSQL .= "metaphone = dmetaphone_alt($sWordQuoted) or metaphonealt = dmetaphone_alt($sWordQuoted)) ";
|
||||
$sSQL .= "and len between length($sWordQuoted)-2 and length($sWordQuoted)+2 ";
|
||||
$sSQL .= "and levenshtein($sWordQuoted,word) < 3 ";
|
||||
$sSQL .= "order by levenshtein($sWordQuoted,word) asc, abs(len - length($sWordQuoted)) asc limit 20";
|
||||
$aSimilar = $oDB->getAll($sSQL);
|
||||
return $aSimilar;
|
||||
}
|
47
lib/log.php
Normal file
47
lib/log.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
function logStart(&$oDB, $sType = '', $sQuery = '', $aLanguageList = array())
|
||||
{
|
||||
$aStartTime = explode('.',microtime(true));
|
||||
if (!$aStartTime[1]) $aStartTime[1] = '0';
|
||||
|
||||
$hLog = array(
|
||||
date('Y-m-d H:i:s',$aStartTime[0]).'.'.$aStartTime[1],
|
||||
$_SERVER["REMOTE_ADDR"],
|
||||
$_SERVER['QUERY_STRING'],
|
||||
$sQuery
|
||||
);
|
||||
|
||||
// Log
|
||||
if ($sType == 'search')
|
||||
{
|
||||
$oDB->query('insert into query_log values ('.getDBQuoted($hLog[0]).','.getDBQuoted($hLog[3]).','.getDBQuoted($hLog[1]).')');
|
||||
}
|
||||
|
||||
$sSQL = 'insert into new_query_log (type,starttime,query,ipaddress,useragent,language,format)';
|
||||
$sSQL .= ' values ('.getDBQuoted($sType).','.getDBQuoted($hLog[0]).','.getDBQuoted($hLog[2]);
|
||||
$sSQL .= ','.getDBQuoted($hLog[1]).','.getDBQuoted($_SERVER['HTTP_USER_AGENT']).','.getDBQuoted(join(',',$aLanguageList)).','.getDBQuoted($_GET['format']).')';
|
||||
$oDB->query($sSQL);
|
||||
|
||||
|
||||
return $hLog;
|
||||
}
|
||||
|
||||
function logEnd(&$oDB, $hLog, $iNumResults)
|
||||
{
|
||||
$aEndTime = explode('.',microtime(true));
|
||||
if (!$aEndTime[1]) $aEndTime[1] = '0';
|
||||
$sEndTime = date('Y-m-d H:i:s',$aEndTime[0]).'.'.$aEndTime[1];
|
||||
|
||||
$sSQL = 'update query_log set endtime = '.getDBQuoted($sEndTime).', results = '.$iNumResults;
|
||||
$sSQL .= ' where starttime = '.getDBQuoted($hLog[0]);
|
||||
$sSQL .= ' and ipaddress = '.getDBQuoted($hLog[1]);
|
||||
$sSQL .= ' and query = '.getDBQuoted($hLog[3]);
|
||||
$oDB->query($sSQL);
|
||||
|
||||
$sSQL = 'update new_query_log set endtime = '.getDBQuoted($sEndTime).', results = '.$iNumResults;
|
||||
$sSQL .= ' where starttime = '.getDBQuoted($hLog[0]);
|
||||
$sSQL .= ' and ipaddress = '.getDBQuoted($hLog[1]);
|
||||
$sSQL .= ' and query = '.getDBQuoted($hLog[2]);
|
||||
$oDB->query($sSQL);
|
||||
}
|
4
module/Makefile
Normal file
4
module/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
MODULES = nominatim
|
||||
PGXS := $(shell pg_config --pgxs)
|
||||
include $(PGXS)
|
||||
|
287
module/nominatim.c
Normal file
287
module/nominatim.c
Normal file
@ -0,0 +1,287 @@
|
||||
#include "postgres.h"
|
||||
#include "fmgr.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include <utfasciitable.h>
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
Datum transliteration( PG_FUNCTION_ARGS );
|
||||
Datum gettokenstring( PG_FUNCTION_ARGS );
|
||||
void str_replace(char* buffer, int* len, int* changes, char* from, int fromlen, char* to, int tolen, int);
|
||||
void str_dupspaces(char* buffer);
|
||||
|
||||
PG_FUNCTION_INFO_V1( transliteration );
|
||||
Datum
|
||||
transliteration( PG_FUNCTION_ARGS )
|
||||
{
|
||||
static char * ascii = UTFASCII;
|
||||
static uint16 asciilookup[65536] = UTFASCIILOOKUP;
|
||||
char * asciipos;
|
||||
|
||||
text *source;
|
||||
unsigned char *sourcedata;
|
||||
int sourcedatalength;
|
||||
|
||||
unsigned int c1,c2,c3,c4;
|
||||
unsigned int * wchardata;
|
||||
unsigned int * wchardatastart;
|
||||
|
||||
text *result;
|
||||
unsigned char *resultdata;
|
||||
int resultdatalength;
|
||||
int iLen;
|
||||
|
||||
if (GetDatabaseEncoding() != PG_UTF8)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("requires UTF8 database encoding")));
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
{
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
// The original string
|
||||
source = PG_GETARG_TEXT_P(0);
|
||||
sourcedata = (unsigned char *)VARDATA(source);
|
||||
sourcedatalength = VARSIZE(source) - VARHDRSZ;
|
||||
|
||||
// Intermediate wchar version of string
|
||||
wchardatastart = wchardata = (unsigned int *)palloc((sourcedatalength+1)*sizeof(int));
|
||||
|
||||
// Based on pg_utf2wchar_with_len from wchar.c
|
||||
while (sourcedatalength > 0 && *sourcedata)
|
||||
{
|
||||
if ((*sourcedata & 0x80) == 0)
|
||||
{
|
||||
*wchardata = *sourcedata++;
|
||||
wchardata++;
|
||||
sourcedatalength--;
|
||||
}
|
||||
else if ((*sourcedata & 0xe0) == 0xc0)
|
||||
{
|
||||
if (sourcedatalength < 2) break;
|
||||
c1 = *sourcedata++ & 0x1f;
|
||||
c2 = *sourcedata++ & 0x3f;
|
||||
*wchardata = (c1 << 6) | c2;
|
||||
wchardata++;
|
||||
sourcedatalength -= 2;
|
||||
}
|
||||
else if ((*sourcedata & 0xf0) == 0xe0)
|
||||
{
|
||||
if (sourcedatalength < 3) break;
|
||||
c1 = *sourcedata++ & 0x0f;
|
||||
c2 = *sourcedata++ & 0x3f;
|
||||
c3 = *sourcedata++ & 0x3f;
|
||||
*wchardata = (c1 << 12) | (c2 << 6) | c3;
|
||||
wchardata++;
|
||||
sourcedatalength -= 3;
|
||||
}
|
||||
else if ((*sourcedata & 0xf8) == 0xf0)
|
||||
{
|
||||
if (sourcedatalength < 4) break;
|
||||
c1 = *sourcedata++ & 0x07;
|
||||
c2 = *sourcedata++ & 0x3f;
|
||||
c3 = *sourcedata++ & 0x3f;
|
||||
c4 = *sourcedata++ & 0x3f;
|
||||
*wchardata = (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
|
||||
wchardata++;
|
||||
sourcedatalength -= 4;
|
||||
}
|
||||
else if ((*sourcedata & 0xfc) == 0xf8)
|
||||
{
|
||||
// table does not extend beyond 4 char long, just skip
|
||||
if (sourcedatalength < 5) break;
|
||||
sourcedatalength -= 5;
|
||||
}
|
||||
else if ((*sourcedata & 0xfe) == 0xfc)
|
||||
{
|
||||
// table does not extend beyond 4 char long, just skip
|
||||
if (sourcedatalength < 6) break;
|
||||
sourcedatalength -= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// assume lenngth 1, silently drop bogus characters
|
||||
sourcedatalength--;
|
||||
}
|
||||
}
|
||||
*wchardata = 0;
|
||||
|
||||
// calc the length of transliteration string
|
||||
resultdatalength = 0;
|
||||
wchardata = wchardatastart;
|
||||
while(*wchardata)
|
||||
{
|
||||
if (*(asciilookup + *wchardata) > 0) resultdatalength += *(ascii + *(asciilookup + *wchardata));
|
||||
wchardata++;
|
||||
}
|
||||
|
||||
// allocate & create the result
|
||||
result = (text *)palloc(resultdatalength + VARHDRSZ);
|
||||
SET_VARSIZE(result, resultdatalength + VARHDRSZ);
|
||||
resultdata = (unsigned char *)VARDATA(result);
|
||||
|
||||
wchardata = wchardatastart;
|
||||
while(*wchardata)
|
||||
{
|
||||
if (*(asciilookup + *wchardata) > 0)
|
||||
{
|
||||
asciipos = ascii + *(asciilookup + *wchardata);
|
||||
for(iLen = *asciipos; iLen > 0; iLen--)
|
||||
{
|
||||
asciipos++;
|
||||
*resultdata = *asciipos;
|
||||
resultdata++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport( WARNING, ( errcode( ERRCODE_SUCCESSFUL_COMPLETION ),
|
||||
errmsg( "missing char: %i\n", *wchardata )));
|
||||
|
||||
}
|
||||
wchardata++;
|
||||
}
|
||||
|
||||
pfree(wchardatastart);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
void str_replace(char* buffer, int* len, int* changes, char* from, int fromlen, char* to, int tolen, int isspace)
|
||||
{
|
||||
char *p;
|
||||
|
||||
// Search string is too long to be pressent
|
||||
if (fromlen > *len) return;
|
||||
|
||||
p = strstr(buffer, from);
|
||||
while(p)
|
||||
{
|
||||
if (!isspace || *(p-1) != ' ')
|
||||
{
|
||||
(*changes)++;
|
||||
if (tolen != fromlen) memmove(p+tolen, p+fromlen, *len-(p-buffer)+1);
|
||||
memcpy(p, to, tolen);
|
||||
*len += tolen - fromlen;
|
||||
}
|
||||
p = strstr(p+1, from);
|
||||
}
|
||||
}
|
||||
|
||||
void str_dupspaces(char* buffer)
|
||||
{
|
||||
char *out;
|
||||
int wasspace;
|
||||
|
||||
out = buffer;
|
||||
wasspace = 0;
|
||||
while(*buffer)
|
||||
{
|
||||
if (wasspace && *buffer != ' ') wasspace = 0;
|
||||
if (!wasspace)
|
||||
{
|
||||
*out = *buffer;
|
||||
out++;
|
||||
wasspace = (*buffer == ' ');
|
||||
}
|
||||
buffer++;
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1( gettokenstring );
|
||||
Datum
|
||||
gettokenstring( PG_FUNCTION_ARGS )
|
||||
{
|
||||
text *source;
|
||||
unsigned char *sourcedata;
|
||||
int sourcedatalength;
|
||||
|
||||
char * buffer;
|
||||
int len;
|
||||
int changes;
|
||||
|
||||
text *result;
|
||||
|
||||
if (GetDatabaseEncoding() != PG_UTF8)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("requires UTF8 database encoding")));
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
{
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
// The original string
|
||||
source = PG_GETARG_TEXT_P(0);
|
||||
sourcedata = (unsigned char *)VARDATA(source);
|
||||
sourcedatalength = VARSIZE(source) - VARHDRSZ;
|
||||
|
||||
// Buffer for doing the replace in - string could get slightly longer (double is mastive overkill)
|
||||
buffer = (char *)palloc((sourcedatalength*2)*sizeof(char));
|
||||
memcpy(buffer+1, sourcedata, sourcedatalength);
|
||||
buffer[0] = 32;
|
||||
buffer[sourcedatalength+1] = 32;
|
||||
buffer[sourcedatalength+2] = 0;
|
||||
len = sourcedatalength+3;
|
||||
|
||||
changes = 1;
|
||||
str_dupspaces(buffer);
|
||||
while(changes)
|
||||
{
|
||||
changes = 0;
|
||||
#include <tokenstringreplacements.inc>
|
||||
str_dupspaces(buffer);
|
||||
}
|
||||
|
||||
// 'and' in various languages
|
||||
str_replace(buffer, &len, &changes, " and ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " und ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " en ", 4, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " et ", 4, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " e ", 3, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " y ", 3, " ", 1, 0);
|
||||
|
||||
// 'the' (and similar)
|
||||
str_replace(buffer, &len, &changes, " the ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " der ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " den ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " die ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " das ", 5, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " la ", 4, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " le ", 4, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " el ", 4, " ", 1, 0);
|
||||
str_replace(buffer, &len, &changes, " il ", 4, " ", 1, 0);
|
||||
|
||||
// german
|
||||
str_replace(buffer, &len, &changes, "ae", 2, "a", 1, 0);
|
||||
str_replace(buffer, &len, &changes, "oe", 2, "o", 1, 0);
|
||||
str_replace(buffer, &len, &changes, "ue", 2, "u", 1, 0);
|
||||
str_replace(buffer, &len, &changes, "sss", 3, "ss", 2, 0);
|
||||
str_replace(buffer, &len, &changes, "ih", 2, "i", 1, 0);
|
||||
str_replace(buffer, &len, &changes, "eh", 2, "e", 1, 0);
|
||||
|
||||
// russian
|
||||
str_replace(buffer, &len, &changes, "ie", 2, "i", 1, 0);
|
||||
str_replace(buffer, &len, &changes, "yi", 2, "i", 1, 0);
|
||||
|
||||
// allocate & create the result
|
||||
len--;// Drop the terminating zero
|
||||
result = (text *)palloc(len + VARHDRSZ);
|
||||
SET_VARSIZE(result, len + VARHDRSZ);
|
||||
memcpy(VARDATA(result), buffer, len);
|
||||
|
||||
pfree(buffer);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
876
module/tokenstringreplacements.inc
Normal file
876
module/tokenstringreplacements.inc
Normal file
@ -0,0 +1,876 @@
|
||||
str_replace(buffer, &len, &changes, " national wildlife refuge area ", 31, " nwra ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " national recreation area ", 26, " nra ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " air national guard base ", 25, " angb ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " zhilishchien komplieks ", 24, " zh k ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " trung tam thuong mdhi ", 23, " tttm ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " poligono industrial ", 21, " pgind ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " trung hoc pho thong ", 21, " thpt ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " onze lieve vrouw e ", 20, " olv ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " strada provinciale ", 20, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "onze lieve vrouw e ", 19, " olv ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " punto kilometrico ", 19, " pk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cong vien van hoa ", 19, " cvvh ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " can cu khong quan ", 19, " cckq ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "strada provinciale ", 19, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " strada regionale ", 18, " sr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " strada comunale ", 17, " sc ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "strada regionale ", 17, " sr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " trung hoc co so ", 17, " thcs ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " san bay quoc te ", 17, " sbqt ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cong ty co phyn ", 17, " ctcp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " khu cong nghiep ", 17, " kcn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " air force base ", 16, " afb ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " strada statale ", 16, " ss ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vien bcyo tang ", 16, " vbt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "strada comunale ", 16, " sc ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " circunvalacion ", 16, " ccvcn ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " paseo maritimo ", 16, " psmar ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " wielkopolskie ", 15, " wlkp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " national park ", 15, " np ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " middle school ", 15, " ms ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " international ", 15, " intl ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " burgermeister ", 15, " bgm ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " vuon quoc gia ", 15, " vqg ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " qucyng truong ", 15, " qt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "strada statale ", 15, " ss ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " state highway ", 15, " sh ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "burgermeister ", 14, " bgm ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " right of way ", 14, " rowy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " hauptbahnhof ", 14, " hbf ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " apartamentos ", 14, " aptos ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " wielkopolski ", 14, " wlkp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " burgemeester ", 14, " bg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " camino nuevo ", 14, " c n ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " camino hondo ", 14, " c h ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " urbanizacion ", 14, " urb ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " camino viejo ", 14, " c v ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " wielkopolska ", 14, " wlkp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " wojewodztwie ", 14, " woj ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " county route ", 14, " cr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " prolongacion ", 14, " prol ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " thoroughfare ", 14, " thor ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " san van dong ", 14, " svd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " tong cong ty ", 14, " tct ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " khu nghi mat ", 14, " knm ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " nha thi dzu ", 13, " ntd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " khu du lich ", 13, " kdl ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " demarcacion ", 13, " demar ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " cau ldhc bo ", 13, " clb ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " interchange ", 13, " intg ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " distributor ", 13, " dstr ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " state route ", 13, " sr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " wojewodztwo ", 13, " woj ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " reservation ", 13, " res ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " monseigneur ", 13, " mgr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " transversal ", 13, " trval ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " extrarradio ", 13, " extrr ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " high school ", 13, " hs ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " mazowieckie ", 13, " maz ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " residencial ", 13, " resid ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " cong truong ", 13, " ct ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cooperativa ", 13, " coop ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " diseminado ", 12, " disem ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " barranquil ", 12, " bqllo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " fire track ", 12, " ftrk ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " south east ", 12, " se ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " north east ", 12, " ne ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " university ", 12, " univ ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " south west ", 12, " sw ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " monasterio ", 12, " mtrio ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " vecindario ", 12, " vecin ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " carreterin ", 12, " ctrin ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " callejuela ", 12, " cjla ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " north-east ", 12, " ne ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " south-west ", 12, " sw ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gebroeders ", 12, " gebr ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " serviceway ", 12, " swy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " quadrangle ", 12, " qdgl ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " commandant ", 12, " cmdt ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " extramuros ", 12, " extrm ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " escalinata ", 12, " escal ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " north-west ", 12, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " bulevardul ", 12, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " particular ", 12, " parti ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " mazowiecka ", 12, " maz ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " mazowiecki ", 12, " maz ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " north west ", 12, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " industrial ", 12, " ind ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " costanilla ", 12, " cstan ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " khach sdhn ", 12, " ks ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " south-east ", 12, " se ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " phi truong ", 12, " pt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " expressway ", 12, " exp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " fondamenta ", 12, " f ta ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " apartments ", 12, " apts ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cul de sac ", 12, " cds ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " corralillo ", 12, " crrlo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " mitropolit ", 12, " mit ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " etorbidea ", 11, " etorb ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " ploshchad ", 11, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cobertizo ", 11, " cbtiz ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " underpass ", 11, " upas ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " crossroad ", 11, " crd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " fundatura ", 11, " fnd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " foreshore ", 11, " fshr ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " parklands ", 11, " pkld ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " esplanade ", 11, " esp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " centreway ", 11, " cnwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " formation ", 11, " form ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " explanada ", 11, " expla ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " viviendas ", 11, " vvdas ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " northeast ", 11, " ne ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cong vien ", 11, " cv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " northwest ", 11, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " buildings ", 11, " bldgs ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " errepidea ", 11, " err ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " extension ", 11, " ex ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " municipal ", 11, " mun ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " southeast ", 11, " se ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sanatorio ", 11, " sanat ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " thanh pho ", 11, " tp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " firetrail ", 11, " fit ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " santuario ", 11, " santu ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " southwest ", 11, " sw ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " autopista ", 11, " auto ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " president ", 11, " pres ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " rinconada ", 11, " rcda ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " kardinaal ", 11, " kard ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " plazoleta ", 11, " pzta ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " duong sat ", 11, " ds ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " trung tam ", 11, " tt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " piazzetta ", 11, " pta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " boardwalk ", 11, " bwlk ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " bulievard ", 11, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " luitenant ", 11, " luit ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " courtyard ", 11, " ctyd ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " reservoir ", 11, " res ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " bulevardu ", 11, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " community ", 11, " comm ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " concourse ", 11, " con ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " profiesor ", 11, " prof ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " promenade ", 11, " prom ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " gienieral ", 11, " ghien ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " puistikko ", 11, " pko ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " balneario ", 11, " balnr ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " carretera ", 11, " ctra ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " ingenieur ", 11, " ir ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " boulevard ", 11, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " deviation ", 11, " devn ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " hipodromo ", 11, " hipod ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " professor ", 11, " prof ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " triangle ", 10, " tri ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " dotsient ", 10, " dots ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " boundary ", 10, " bdy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " salizada ", 10, " s da ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " trunkway ", 10, " tkwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cinturon ", 10, " cint ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "president ", 10, " pres ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " military ", 10, " mil ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " jonkheer ", 10, " jhr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " motorway ", 10, " mwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " steenweg ", 10, " stwg ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " crescent ", 10, " cr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kanunnik ", 10, " kan ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " koningin ", 10, " kon ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " crossing ", 10, " xing ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " callejon ", 10, " cjon ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " pasadizo ", 10, " pzo ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " crossway ", 10, " cowy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cottages ", 10, " cotts ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " mountain ", 10, " mtn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " business ", 10, " bus ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " pierwszy ", 10, " 1 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " pierwsza ", 10, " 1 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " pierwsze ", 10, " 1 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " barriada ", 10, " barda ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " entrance ", 10, " ent ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " causeway ", 10, " cway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " generaal ", 10, " gen ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " driveway ", 10, " dvwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " township ", 10, " twp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " stazione ", 10, " staz ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " broadway ", 10, " bway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " alleyway ", 10, " alwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " quadrant ", 10, " qdrt ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " apeadero ", 10, " apdro ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " arboleda ", 10, " arb ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " escalera ", 10, " esca ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " rdhp hat ", 10, " rh ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " transito ", 10, " trans ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " ddhi hoc ", 10, " dh ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " travesia ", 10, " trva ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " barranco ", 10, " branc ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " namestie ", 10, " nam ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " viaducto ", 10, " vcto ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " convento ", 10, " cnvto ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " estacion ", 10, " estcn ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, "puistikko ", 10, " pko ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " precinct ", 10, " pct ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " heiligen ", 10, " hl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " edificio ", 10, " edifc ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " prazuela ", 10, " przla ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " thi trzn ", 10, " tt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ridgeway ", 10, " rgwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " riverway ", 10, " rvwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " corredor ", 10, " crrdo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " passatge ", 10, " ptge ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " junction ", 10, " jnc ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " hospital ", 10, " hosp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " highroad ", 10, " hrd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " torrente ", 10, " trrnt ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " avinguda ", 10, " av ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " portillo ", 10, " ptilo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " diagonal ", 10, " diag ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " buu dien ", 10, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " alqueria ", 10, " alque ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " poligono ", 10, " polig ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " roadside ", 10, " rdsd ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " glorieta ", 10, " gta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " fundacul ", 10, " fdc ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cao dang ", 10, " cd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " rosebowl ", 10, " rsbl ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " complejo ", 10, " compj ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " carretil ", 10, " crtil ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " intrarea ", 10, " int ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " gran via ", 10, " g v ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " approach ", 10, " app ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " stradela ", 10, " sdla ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " conjunto ", 10, " cjto ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " arterial ", 10, " artl ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " plazuela ", 10, " plzla ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " frontage ", 10, " frtg ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " faubourg ", 10, " fg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " mansions ", 10, " mans ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " turnpike ", 10, " tpk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " piazzale ", 10, " p le ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " tieu hoc ", 10, " th ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bulevard ", 10, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sendera ", 9, " sedra ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " cutting ", 9, " cutt ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cantina ", 9, " canti ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " cantera ", 9, " cantr ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " rotonda ", 9, " rtda ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " pasillo ", 9, " psllo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " landing ", 9, " ldg ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " kolonel ", 9, " kol ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cong ty ", 9, " cty ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " fairway ", 9, " fawy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " highway ", 9, " hwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " lookout ", 9, " lkt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " meander ", 9, " mr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " carrera ", 9, " cra ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " station ", 9, " stn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " kapitan ", 9, " kap ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " medical ", 9, " med ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " broeder ", 9, " br ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " poblado ", 9, " pbdo ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " impasse ", 9, " imp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " gardens ", 9, " gdn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " nha tho ", 9, " nt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " nha hat ", 9, " nh ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " freeway ", 9, " fwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " trasera ", 9, " tras ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " portico ", 9, " prtco ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " terrace ", 9, " ter ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " heights ", 9, " hts ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " camping ", 9, " campg ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " callizo ", 9, " cllzo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " footway ", 9, " ftwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " calzada ", 9, " czada ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " dominee ", 9, " ds ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " meadows ", 9, " mdws ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " sendero ", 9, " send ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " osiedle ", 9, " os ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " estrada ", 9, " estda ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " avenida ", 9, " av ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " zgornji ", 9, " zg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " zgornje ", 9, " zg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " zgornja ", 9, " zg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " arrabal ", 9, " arral ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " espalda ", 9, " eslda ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " entrada ", 9, " entd ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " kleiner ", 9, " kl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kleines ", 9, " kl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " viaduct ", 9, " via ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " roadway ", 9, " rdwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " strasse ", 9, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " spodnje ", 9, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " spodnji ", 9, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " spodnja ", 9, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " fabrica ", 9, " fca ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " muntele ", 9, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " maantee ", 9, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " srednje ", 9, " sr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " unterer ", 9, " u ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " unteres ", 9, " u ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " plateau ", 9, " plat ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " srednji ", 9, " sr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " empresa ", 9, " empr ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " angosta ", 9, " angta ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " costera ", 9, " coste ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " tinh lo ", 9, " tl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " quoc lo ", 9, " ql ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " auf der ", 9, " a d ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " bulvari ", 9, " bl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ddhi lo ", 9, " dl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " namesti ", 9, " nam ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " passeig ", 9, " pg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " carrero ", 9, " cro ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cortijo ", 9, " crtjo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " san bay ", 9, " sb ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " riviera ", 9, " rvra ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " caddesi ", 9, " cd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " andador ", 9, " andad ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " walkway ", 9, " wkwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " granden ", 9, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " grosser ", 9, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " grosses ", 9, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " reserve ", 9, " res ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " alameda ", 9, " alam ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " retreat ", 9, " rtt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " acequia ", 9, " aceq ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " platsen ", 9, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bahnhof ", 9, " bf ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " autovia ", 9, " autov ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " srednja ", 9, " sr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " galeria ", 9, " gale ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " circuit ", 9, " cct ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " svingen ", 9, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " plassen ", 9, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " mirador ", 9, " mrdor ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " laneway ", 9, " lnwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " kolonia ", 9, " kol ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " outlook ", 9, " otlk ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " caravan ", 9, " cvn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " osiedlu ", 9, " os ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " palacio ", 9, " palac ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " pantano ", 9, " pant ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " partida ", 9, " ptda ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " calleja ", 9, " cllja ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " mevrouw ", 9, " mevr ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " meester ", 9, " mr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pastoor ", 9, " past ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " prinses ", 9, " pr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bulevar ", 9, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " tollway ", 9, " tlwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "steenweg ", 9, " stwg ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " caserio ", 9, " csrio ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " mercado ", 9, " merc ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " alejach ", 9, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kvartal ", 9, " kv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " parkway ", 9, " pwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " passage ", 9, " ps ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pathway ", 9, " pway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " splaiul ", 9, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " soseaua ", 9, " sos ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " colonia ", 9, " col ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " wielkie ", 9, " wlk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " trzecie ", 9, " 3 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " llanura ", 9, " llnra ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " malecon ", 9, " malec ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " trzecia ", 9, " 3 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " trailer ", 9, " trlr ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cuadra ", 8, " cuadr ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " cty cp ", 8, " ctcp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " paraje ", 8, " praje ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " parque ", 8, " pque ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " piazza ", 8, " p za ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " puerta ", 8, " pta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " little ", 8, " lt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pueblo ", 8, " pblo ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " puente ", 8, " pnte ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " jardin ", 8, " jdin ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " granja ", 8, " granj ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " market ", 8, " mkt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " pasaje ", 8, " psaje ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " rotary ", 8, " rty ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " corral ", 8, " crral ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " siding ", 8, " sdng ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " nucleo ", 8, " ncleo ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " muelle ", 8, " muell ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " carril ", 8, " crril ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " portal ", 8, " prtal ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " ramble ", 8, " rmbl ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " pocket ", 8, " pkt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " chalet ", 8, " chlet ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " canton ", 8, " cant ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " ladera ", 8, " ldera ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " parade ", 8, " pde ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " dehesa ", 8, " dhsa ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " museum ", 8, " mus ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " middle ", 8, " mid ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cuesta ", 8, " custa ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " gracht ", 8, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " virful ", 8, " vf ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " m tele ", 8, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " varful ", 8, " vf ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " str la ", 8, " sdla ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " arcade ", 8, " arc ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " strada ", 8, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " access ", 8, " accs ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " bajada ", 8, " bjada ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " veliki ", 8, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "strasse ", 8, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " velike ", 8, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " untere ", 8, " u ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " velika ", 8, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " artery ", 8, " arty ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " avenue ", 8, " av ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " miasto ", 8, " m ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " bypass ", 8, " byp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " placem ", 8, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " barrio ", 8, " bo ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " center ", 8, " ctr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " bldngs ", 8, " bldgs ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " puerto ", 8, " pto ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " wielka ", 8, " wlk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " tunnel ", 8, " tun ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " wielki ", 8, " wlk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " bridge ", 8, " bri ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " trzeci ", 8, " 3 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " veliko ", 8, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " quelle ", 8, " qu ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " acceso ", 8, " acces ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " bulvar ", 8, " bl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sokagi ", 8, " sk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "platsen ", 8, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " stigen ", 8, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " brucke ", 8, " br ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " an der ", 8, " a d ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " thi xa ", 8, " tx ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " nordre ", 8, " ndr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " rambla ", 8, " rbla ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " sondre ", 8, " sdr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "quoc lo ", 8, " ql ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " phuong ", 8, " p ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " vastra ", 8, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " carrer ", 8, " c ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " oberes ", 8, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " raitti ", 8, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " puisto ", 8, " ps ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " arroyo ", 8, " arry ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " penger ", 8, " pgr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " oberer ", 8, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " kleine ", 8, " kl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " grosse ", 8, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "granden ", 8, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " villas ", 8, " vlls ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " taival ", 8, " tvl ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " in der ", 8, " i d ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " centre ", 8, " ctr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " drugie ", 8, " 2 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " dokter ", 8, " dr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " grange ", 8, " gra ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " doctor ", 8, " dr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vicolo ", 8, " v lo ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " kort e ", 8, " k ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " koning ", 8, " kon ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " straat ", 8, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " svieti ", 8, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " callej ", 8, " cjon ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " ground ", 8, " grnd ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " vereda ", 8, " vreda ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " chemin ", 8, " ch ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " street ", 8, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " strand ", 8, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sainte ", 8, " ste ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " camino ", 8, " cno ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " garden ", 8, " gdn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " follow ", 8, " folw ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " estate ", 8, " est ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " doktor ", 8, " d r ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " subway ", 8, " sbwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " ulitsa ", 8, " ul ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " square ", 8, " sq ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " towers ", 8, " twrs ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "plassen ", 8, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " county ", 8, " co ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " brazal ", 8, " brzal ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " circus ", 8, " crcs ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "svingen ", 8, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " rampla ", 8, " rampa ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " bloque ", 8, " blque ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " circle ", 8, " cir ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " island ", 8, " is ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " common ", 8, " comm ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " ribera ", 8, " rbra ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " sector ", 8, " sect ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " rincon ", 8, " rcon ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " van de ", 8, " vd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " corner ", 8, " cnr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " subida ", 8, " sbida ", 7, 0);
|
||||
str_replace(buffer, &len, &changes, " banda ", 7, " b ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " bulev ", 7, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " barro ", 7, " bo ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cllon ", 7, " cjon ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " p zza ", 7, " p za ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " drugi ", 7, " 2 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " druga ", 7, " 2 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " placu ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " aleji ", 7, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " aleja ", 7, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " aleje ", 7, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " stary ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " stara ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " dolny ", 7, " dln ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " dolna ", 7, " dln ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " gorne ", 7, " gn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gorna ", 7, " gn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " stare ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gorny ", 7, " gn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ulicy ", 7, " ul ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ulica ", 7, " ul ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " o l v ", 7, " olv ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " plein ", 7, " pln ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " markt ", 7, " mkt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " lange ", 7, " l ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " viale ", 7, " v le ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "gracht ", 7, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " prins ", 7, " pr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "straat ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " plass ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sving ", 7, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gaten ", 7, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " veien ", 7, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " vliet ", 7, " vlt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " dolne ", 7, " dln ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " b dul ", 7, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sodra ", 7, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " norra ", 7, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " gamla ", 7, " gla ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " grand ", 7, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vagen ", 7, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " gatan ", 7, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " ostra ", 7, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "vastra ", 7, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " cadde ", 7, " cd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " duong ", 7, " d ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " sokak ", 7, " sk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " plats ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "stigen ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vayla ", 7, " vla ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "taival ", 7, " tvl ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " sveti ", 7, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " aukio ", 7, " auk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " sveta ", 7, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cesta ", 7, " c ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " piata ", 7, " pta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " aleea ", 7, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kaari ", 7, " kri ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "penger ", 7, " pgr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " ranta ", 7, " rt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " rinne ", 7, " rn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "raitti ", 7, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "puisto ", 7, " ps ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " polku ", 7, " p ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " porta ", 7, " pta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " ponte ", 7, " p te ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " paseo ", 7, " po ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " fbrca ", 7, " fca ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " allee ", 7, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cours ", 7, " crs ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "sainte ", 7, " ste ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "square ", 7, " sq ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " largo ", 7, " l go ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " wharf ", 7, " whrf ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " corte ", 7, " c te ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " corso ", 7, " c so ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " campo ", 7, " c po ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " santa ", 7, " sta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " calle ", 7, " c ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " strip ", 7, " strp ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " alley ", 7, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " north ", 7, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " block ", 7, " blk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " gully ", 7, " gly ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " sielo ", 7, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " brace ", 7, " br ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ronde ", 7, " rnde ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " grove ", 7, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " break ", 7, " brk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " roads ", 7, " rds ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " track ", 7, " trk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " house ", 7, " ho ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " trail ", 7, " trl ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " mount ", 7, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cross ", 7, " crss ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " beach ", 7, " bch ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " point ", 7, " pt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " basin ", 7, " basn ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " green ", 7, " gn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " plaza ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " lille ", 7, " ll ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " slope ", 7, " slpe ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " placa ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " place ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " shunt ", 7, " shun ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " saint ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ulice ", 7, " ul ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " amble ", 7, " ambl ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " route ", 7, " rt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sound ", 7, " snd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " store ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " front ", 7, " frnt ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " elbow ", 7, " elb ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " glade ", 7, " gl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " south ", 7, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " round ", 7, " rnd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " drive ", 7, " dr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " croft ", 7, " cft ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " platz ", 7, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ferry ", 7, " fy ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ridge ", 7, " rdge ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " tanav ", 7, " tn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " banan ", 7, " ba ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " quays ", 7, " qys ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " sankt ", 7, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vkhod ", 7, " vkh ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " chase ", 7, " ch ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vista ", 7, " vsta ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " rhein ", 7, " rh ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " court ", 7, " ct ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "brucke ", 7, " br ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " upper ", 7, " up ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " river ", 7, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " range ", 7, " rnge ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " lower ", 7, " lr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kalea ", 7, " k ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " crest ", 7, " crst ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " obere ", 7, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " manor ", 7, " mnr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " byway ", 7, " bywy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " reach ", 7, " rch ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " copse ", 7, " cps ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "quelle ", 7, " qu ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " creek ", 7, " cr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " close ", 7, " c ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " fort ", 6, " ft ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " apch ", 6, " app ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " mont ", 6, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bdul ", 6, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "saint ", 6, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " back ", 6, " bk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " c le ", 6, " c ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "place ", 6, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " frwy ", 6, " fwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " quai ", 6, " qu ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ally ", 6, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " m te ", 6, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " lane ", 6, " ln ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "aukio ", 6, " auk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " loop ", 6, " lp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " line ", 6, " ln ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " alue ", 6, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " link ", 6, " lk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " glde ", 6, " gl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " alea ", 6, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gate ", 6, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " intr ", 6, " int ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " gdns ", 6, " gdn ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " hird ", 6, " hrd ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " varf ", 6, " vf ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " virf ", 6, " vf ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " hgts ", 6, " hts ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " expy ", 6, " exp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "markt ", 6, " mkt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " bypa ", 6, " byp ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "o l v ", 6, " olv ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cres ", 6, " cr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bdwy ", 6, " bway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " csac ", 6, " cds ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " nowy ", 6, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " laan ", 6, " ln ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " crsg ", 6, " xing ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "vliet ", 6, " vlt ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " city ", 6, " cty ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "sving ", 6, " sv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "plass ", 6, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "gaten ", 6, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "veien ", 6, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " gata ", 6, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " sint ", 6, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " caus ", 6, " cway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " cove ", 6, " cv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "plein ", 6, " pln ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cswy ", 6, " cway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " plac ", 6, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " nowa ", 6, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " kolo ", 6, " k ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " katu ", 6, " k ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " duze ", 6, " dz ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " blvd ", 6, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " p ta ", 6, " pta ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " maly ", 6, " ml ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " mala ", 6, " ml ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bdge ", 6, " bri ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " nowe ", 6, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " brdg ", 6, " bri ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " male ", 6, " ml ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " drwy ", 6, " dvwy ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " duza ", 6, " dz ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " utca ", 6, " u ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " east ", 6, " e ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " duzy ", 6, " dz ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "kaari ", 6, " kri ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " quan ", 6, " q ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " svwy ", 6, " swy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " shwy ", 6, " sh ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " road ", 6, " rd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "sankt ", 6, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " quay ", 6, " qy ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "plats ", 6, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " rise ", 6, " ri ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " berg ", 6, " bg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " tcty ", 6, " tct ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " viad ", 6, " via ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " view ", 6, " vw ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vdct ", 6, " via ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " vale ", 6, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " avda ", 6, " av ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " grad ", 6, " ghr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " walk ", 6, " wlk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " west ", 6, " w ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " yard ", 6, " yd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " blok ", 6, " bl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " terr ", 6, " ter ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " cmno ", 6, " cno ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " stra ", 6, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " thfr ", 6, " thor ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " turn ", 6, " tn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " tpke ", 6, " tpk ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " burg ", 6, " bg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "vayla ", 6, " vla ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, "vagen ", 6, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " tori ", 6, " tr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "gatan ", 6, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "grand ", 6, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pass ", 6, " ps ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pkwy ", 6, " pwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " park ", 6, " pk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "rinne ", 6, " rn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " mtwy ", 6, " mwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " mndr ", 6, " mr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kyla ", 6, " kl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kuja ", 6, " kj ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "platz ", 6, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "ranta ", 6, " rt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " mile ", 6, " mi ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pfad ", 6, " p ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " mews ", 6, " m ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "polku ", 6, " p ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " psge ", 6, " ps ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " plza ", 6, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "ostra ", 6, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "gamla ", 6, " gla ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " stig ", 6, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "norra ", 6, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "sodra ", 6, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " pike ", 6, " pk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " dorf ", 6, " df ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " piaz ", 6, " p za ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, " phwy ", 6, " pway ", 6, 0);
|
||||
str_replace(buffer, &len, &changes, "pfad ", 5, " p ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " mnt ", 5, " mt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "gata ", 5, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " bhf ", 5, " bf ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bad ", 5, " b ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "gate ", 5, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " zum ", 5, " z ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "stig ", 5, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " blv ", 5, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "kuja ", 5, " kj ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bul ", 5, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " str ", 5, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "alue ", 5, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cen ", 5, " ctr ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " ave ", 5, " av ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "kyla ", 5, " kl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ale ", 5, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " spl ", 5, " sp ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " all ", 5, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " k s ", 5, " ks ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " aly ", 5, " al ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "dorf ", 5, " df ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bvd ", 5, " bd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " vag ", 5, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " iii ", 5, " 3 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " tie ", 5, " t ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " sok ", 5, " sk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "burg ", 5, " bg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "katu ", 5, " k ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "berg ", 5, " bg ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "tori ", 5, " tr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " kte ", 5, " k ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " gro ", 5, " gr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " grn ", 5, " gn ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gld ", 5, " gl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " san ", 5, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " hse ", 5, " ho ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " gte ", 5, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " rte ", 5, " rt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " rue ", 5, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " che ", 5, " ch ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pas ", 5, " ps ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " plz ", 5, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pnt ", 5, " pt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " pky ", 5, " pwy ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " pza ", 5, " pl ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " rvr ", 5, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " riv ", 5, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " lit ", 5, " lt ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " p k ", 5, " pk ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " lwr ", 5, " lr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " low ", 5, " lr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " sth ", 5, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " crk ", 5, " cr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "pres ", 5, " pres ", 6, 1);
|
||||
str_replace(buffer, &len, &changes, "laan ", 5, " ln ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " bda ", 5, " b ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " vei ", 5, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " via ", 5, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " way ", 5, " wy ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " upr ", 5, " up ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " avd ", 5, " av ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " crt ", 5, " ct ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, "stwg ", 5, " stwg ", 6, 1);
|
||||
str_replace(buffer, &len, &changes, "sint ", 5, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " v d ", 5, " vd ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " van ", 5, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " drv ", 5, " dr ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " tce ", 5, " ter ", 5, 0);
|
||||
str_replace(buffer, &len, &changes, " va ", 4, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " oa ", 4, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " sa ", 4, " s ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " na ", 4, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "bgm ", 4, " bgm ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, " nw ", 4, " n ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "vag ", 4, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " im ", 4, " 1 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "vla ", 4, " vla ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "gla ", 4, " gla ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, " am ", 4, " a ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " ph ", 4, " p ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "rue ", 4, " r ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " ga ", 4, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "ste ", 4, " ste ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "str ", 4, " st ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " cl ", 4, " c ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " vn ", 4, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " gt ", 4, " g ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "vei ", 4, " v ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "vlt ", 4, " vlt ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, " ce ", 4, " cv ", 4, 0);
|
||||
str_replace(buffer, &len, &changes, " ii ", 4, " 2 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "pln ", 4, " pln ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "olv ", 4, " olv ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "mkt ", 4, " mkt ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "tvl ", 4, " tvl ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, " ob ", 4, " o ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "pgr ", 4, " pgr ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, " in ", 4, " 1 ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " mw ", 4, " m ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, "kri ", 4, " kri ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "pko ", 4, " pko ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "auk ", 4, " auk ", 5, 1);
|
||||
str_replace(buffer, &len, &changes, "tie ", 4, " t ", 3, 0);
|
||||
str_replace(buffer, &len, &changes, " i ", 3, " 1 ", 3, 0);
|
2
module/utfasciitable.h
Normal file
2
module/utfasciitable.h
Normal file
File diff suppressed because one or more lines are too long
89
nominatim/Makefile.in
Normal file
89
nominatim/Makefile.in
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
sysconfdir = @sysconfdir@
|
||||
datarootdir = @datarootdir@
|
||||
datadir = @datadir@
|
||||
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
SVN:=$(shell svnversion)
|
||||
DATADIR = $(datadir)/$(PACKAGE)
|
||||
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
|
||||
CFLAGS += -g -O2 -Wall -Wextra
|
||||
CFLAGS += $(shell xml2-config --cflags)
|
||||
CFLAGS += $(shell geos-config --cflags)
|
||||
CFLAGS += -I$(shell pg_config --includedir)
|
||||
CFLAGS += -DVERSION=\"$(VERSION)-$(SVN)\"
|
||||
CFLAGS += -DHAVE_PTHREAD
|
||||
CFLAGS += -DNOMINATIM_DATADIR=\"$(DATADIR)\"
|
||||
|
||||
LDFLAGS += $(shell xml2-config --libs)
|
||||
LDFLAGS += $(shell geos-config --libs)
|
||||
LDFLAGS += -L$(shell pg_config --libdir) -lpq
|
||||
LDFLAGS += -lbz2 -lz
|
||||
LDFLAGS += -g -lproj
|
||||
LDFLAGS += -lstdc++
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
SRCS:=$(wildcard *.c) $(wildcard *.cpp)
|
||||
OBJS:=$(SRCS:.c=.o)
|
||||
OBJS:=$(OBJS:.cpp=.o)
|
||||
DEPS:=$(SRCS:.c=.d)
|
||||
DEPS:=$(DEPS:.cpp=.d)
|
||||
|
||||
APPS:=nominatim
|
||||
DATA:=default.style
|
||||
|
||||
.PHONY: all clean $(PACKAGE).spec
|
||||
|
||||
all: $(APPS)
|
||||
|
||||
clean:
|
||||
rm -f $(APPS) $(OBJS) $(DEPS)
|
||||
rm -f $(PACKAGE)-*.tar.bz2
|
||||
rm -f nominatim.spec
|
||||
|
||||
clean-all: clean
|
||||
rm -rf autom4te.cache
|
||||
rm -f config.h
|
||||
rm -f config.log
|
||||
rm -f config.status
|
||||
rm -f configure
|
||||
rm -f Makefile
|
||||
|
||||
install: $(APPS)
|
||||
mkdir -p $(DESTDIR)$(bindir)
|
||||
install -m 0755 $(APPS) $(DESTDIR)$(bindir)
|
||||
mkdir -p $(DESTDIR)$(DATADIR)
|
||||
install -m 0644 $(DATA) $(DESTDIR)$(DATADIR)
|
||||
|
||||
%.d: %.c
|
||||
@set -e; rm -f $@; \
|
||||
$(CC) -MM $(CFLAGS) $< > $@.$$$$; \
|
||||
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
||||
rm -f $@.$$$$
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
nominatim: $(OBJS)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
$(PACKAGE).spec: $(PACKAGE).spec.in
|
||||
sed -e "s/@PACKAGE@/$(PACKAGE)/g; s/@VERSION@/$(VERSION)/g; s/@SVN@/$(SVN)/g;" $^ > $@
|
||||
|
||||
$(PACKAGE)-$(VERSION).tar.bz2: $(PACKAGE).spec
|
||||
rm -fR tmp
|
||||
mkdir -p tmp/nominatim
|
||||
cp -p Makefile *.[ch] *.cpp README.txt nominatim-svn.sh tmp/nominatim
|
||||
cp -p nominatim.spec tmp/
|
||||
tar cjf $@ -C tmp .
|
||||
rm -fR tmp
|
||||
|
||||
rpm: $(PACKAGE)-$(VERSION).tar.bz2
|
||||
rpmbuild -ta $^
|
0
nominatim/README.txt
Normal file
0
nominatim/README.txt
Normal file
2
nominatim/autogen.sh
Executable file
2
nominatim/autogen.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
autoconf
|
19
nominatim/config.h.in
Normal file
19
nominatim/config.h.in
Normal file
@ -0,0 +1,19 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
15
nominatim/configure.ac
Normal file
15
nominatim/configure.ac
Normal file
@ -0,0 +1,15 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(nominatim, 0.1)
|
||||
|
||||
dnl Generate configuration header file
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Find C compiler
|
||||
AC_PROG_CC
|
||||
|
||||
dnl Find C++ compiler
|
||||
AC_PROG_CXX
|
||||
|
||||
dnl Generate Makefile
|
||||
AC_OUTPUT(Makefile)
|
||||
|
412
nominatim/export.c
Normal file
412
nominatim/export.c
Normal file
@ -0,0 +1,412 @@
|
||||
/*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#include "nominatim.h"
|
||||
#include "export.h"
|
||||
#include "postgresql.h"
|
||||
|
||||
extern int verbose;
|
||||
|
||||
void nominatim_export(int rank_min, int rank_max, const char *conninfo, const char *structuredoutputfile)
|
||||
{
|
||||
xmlTextWriterPtr writer;
|
||||
|
||||
int rankTotalDone;
|
||||
|
||||
PGconn *conn;
|
||||
PGresult * res;
|
||||
PGresult * resSectors;
|
||||
PGresult * resPlaces;
|
||||
|
||||
int rank;
|
||||
int i;
|
||||
int iSector;
|
||||
int tuples;
|
||||
|
||||
const char *paramValues[2];
|
||||
int paramLengths[2];
|
||||
int paramFormats[2];
|
||||
uint32_t paramRank;
|
||||
uint32_t paramSector;
|
||||
uint32_t sector;
|
||||
|
||||
Oid pg_prepare_params[2];
|
||||
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK) {
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sectors",
|
||||
"select geometry_sector,count(*) from placex where rank_search = $1 and indexed = true group by geometry_sector order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
pg_prepare_params[1] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sector_places",
|
||||
"select place_id from placex where rank_search = $1 and geometry_sector = $2",
|
||||
2, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
nominatim_exportCreatePreparedQueries(conn);
|
||||
|
||||
// Create the output file
|
||||
writer = nominatim_exportXMLStart(structuredoutputfile);
|
||||
|
||||
for (rank = rank_min; rank <= rank_max; rank++)
|
||||
{
|
||||
printf("Starting rank %d\n", rank);
|
||||
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
resSectors = PQexecPrepared(conn, "index_sectors", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resSectors) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sectors: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 1) != PG_OID_INT8)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rankTotalDone = 0;
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
sector = PGint32(*((uint32_t *)PQgetvalue(resSectors, iSector, 0)));
|
||||
|
||||
// Get all the place_id's for this sector
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
paramSector = PGint32(sector);
|
||||
paramValues[1] = (char *)¶mSector;
|
||||
paramLengths[1] = sizeof(paramSector);
|
||||
paramFormats[1] = 1;
|
||||
resPlaces = PQexecPrepared(conn, "index_sector_places", 2, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resPlaces) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resPlaces, 0) != PG_OID_INT8)
|
||||
{
|
||||
fprintf(stderr, "Place_id value has unexpected type\n");
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
tuples = PQntuples(resPlaces);
|
||||
for(i = 0; i < tuples; i++)
|
||||
{
|
||||
nominatim_exportPlace(PGint64(*((uint64_t *)PQgetvalue(resPlaces, i, 0))), conn, writer, NULL);
|
||||
rankTotalDone++;
|
||||
if (rankTotalDone%1000 == 0) printf("Done %i (k)\n", rankTotalDone/1000);
|
||||
}
|
||||
PQclear(resPlaces);
|
||||
}
|
||||
PQclear(resSectors);
|
||||
}
|
||||
|
||||
nominatim_exportXMLEnd(writer);
|
||||
|
||||
PQfinish(conn);
|
||||
}
|
||||
|
||||
void nominatim_exportCreatePreparedQueries(PGconn * conn)
|
||||
{
|
||||
Oid pg_prepare_params[2];
|
||||
PGresult * res;
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_details",
|
||||
"select osm_type, osm_id, class, type, name, housenumber, country_code, ST_AsText(geometry), admin_level, rank_address, rank_search from placex where place_id = $1",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_address",
|
||||
"select osm_type,osm_id,class,type,distance,cached_rank_address from place_addressline join placex on (address_place_id = placex.place_id) where isaddress and place_addressline.place_id = $1 and address_place_id != place_addressline.place_id order by cached_rank_address asc",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(conn, "placex_names",
|
||||
"select (each(name)).key,(each(name)).value from (select keyvalueToHStore(name) as name from placex where place_id = $1) as x",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
xmlTextWriterPtr nominatim_exportXMLStart(const char *structuredoutputfile)
|
||||
{
|
||||
xmlTextWriterPtr writer;
|
||||
|
||||
writer = xmlNewTextWriterFilename(structuredoutputfile, 0);
|
||||
if (writer==NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to open %s\n", structuredoutputfile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlTextWriterSetIndent(writer, 1);
|
||||
if (xmlTextWriterStartDocument(writer, NULL, "UTF8", NULL) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterStartDocument failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "osmStructured") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterStartElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "version", BAD_CAST "0.1") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterWriteAttribute failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterWriteAttribute(writer, BAD_CAST "generator", BAD_CAST "Nominatim") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterWriteAttribute failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterStartElement(writer, BAD_CAST "add") < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterStartElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
void nominatim_exportXMLEnd(xmlTextWriterPtr writer)
|
||||
{
|
||||
// End <add>
|
||||
if (xmlTextWriterEndElement(writer) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterEndElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// End <osmStructured>
|
||||
if (xmlTextWriterEndElement(writer) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterEndElement failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (xmlTextWriterEndDocument(writer) < 0)
|
||||
{
|
||||
fprintf(stderr, "xmlTextWriterEndDocument failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlFreeTextWriter(writer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Requirements: the prepared queries must exist
|
||||
*/
|
||||
void nominatim_exportPlace(uint64_t place_id, PGconn * conn, xmlTextWriterPtr writer, pthread_mutex_t * writer_mutex)
|
||||
{
|
||||
PGresult * res;
|
||||
PGresult * resNames;
|
||||
PGresult * resAddress;
|
||||
|
||||
int i;
|
||||
|
||||
const char * paramValues[1];
|
||||
int paramLengths[1];
|
||||
int paramFormats[1];
|
||||
uint64_t paramPlaceID;
|
||||
|
||||
|
||||
paramPlaceID = PGint64(place_id);
|
||||
paramValues[0] = (char *)¶mPlaceID;
|
||||
paramLengths[0] = sizeof(paramPlaceID);
|
||||
paramFormats[0] = 1;
|
||||
|
||||
res = PQexecPrepared(conn, "placex_details", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_details: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
resNames = PQexecPrepared(conn, "placex_names", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resNames) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_names: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resNames);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
resAddress = PQexecPrepared(conn, "placex_address", 1, paramValues, paramLengths, paramFormats, 0);
|
||||
if (PQresultStatus(resAddress) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_address: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resAddress);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (writer_mutex) pthread_mutex_lock( writer_mutex );
|
||||
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "feature");
|
||||
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "place_id", "%li", place_id);
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(res, 0, 0));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST PQgetvalue(res, 0, 1));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST PQgetvalue(res, 0, 2));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST PQgetvalue(res, 0, 3));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "rank", BAD_CAST PQgetvalue(res, 0, 9));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "importance", BAD_CAST PQgetvalue(res, 0, 10));
|
||||
|
||||
if (PQgetvalue(res, 0, 4) && strlen(PQgetvalue(res, 0, 4)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "names");
|
||||
|
||||
for(i = 0; i < PQntuples(resNames); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "name");
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resNames, i, 0));
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(resNames, i, 1));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQgetvalue(res, 0, 5) && strlen(PQgetvalue(res, 0, 5)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "houseNumber");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 5));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQgetvalue(res, 0, 8) && strlen(PQgetvalue(res, 0, 8)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "adminLevel");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 8));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQgetvalue(res, 0, 6) && strlen(PQgetvalue(res, 0, 6)))
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "countryCode");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 6));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
if (PQntuples(resAddress)> 0)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "address");
|
||||
for(i = 0; i < PQntuples(resAddress); i++)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, BAD_CAST getRankLabel(atoi(PQgetvalue(resAddress, i, 5))));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "rank", BAD_CAST PQgetvalue(resAddress, i, 5));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST PQgetvalue(resAddress, i, 0));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "id", BAD_CAST PQgetvalue(resAddress, i, 1));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST PQgetvalue(resAddress, i, 2));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST PQgetvalue(resAddress, i, 3));
|
||||
xmlTextWriterWriteAttribute(writer, BAD_CAST "distance", BAD_CAST PQgetvalue(resAddress, i, 4));
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "osmGeometry");
|
||||
xmlTextWriterWriteString(writer, BAD_CAST PQgetvalue(res, 0, 7));
|
||||
xmlTextWriterEndElement(writer);
|
||||
|
||||
xmlTextWriterEndElement(writer); // </feature>
|
||||
|
||||
if (writer_mutex) pthread_mutex_unlock( writer_mutex );
|
||||
|
||||
PQclear(res);
|
||||
PQclear(resNames);
|
||||
PQclear(resAddress);
|
||||
}
|
||||
|
||||
const char * getRankLabel(int rank)
|
||||
{
|
||||
switch(rank)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return "continent";
|
||||
case 2:
|
||||
case 3:
|
||||
return "sea";
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return "country";
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
return "state";
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return "county";
|
||||
case 16:
|
||||
return "city";
|
||||
case 17:
|
||||
return "town";
|
||||
case 18:
|
||||
return "village";
|
||||
case 19:
|
||||
return "unknown";
|
||||
case 20:
|
||||
return "suburb";
|
||||
case 21:
|
||||
return "postcode";
|
||||
case 22:
|
||||
return "neighborhood";
|
||||
case 23:
|
||||
return "postcode";
|
||||
case 24:
|
||||
return "unknown";
|
||||
case 25:
|
||||
return "postcode";
|
||||
case 26:
|
||||
return "street";
|
||||
case 27:
|
||||
return "access";
|
||||
case 28:
|
||||
return "building";
|
||||
case 29:
|
||||
default:
|
||||
return "other";
|
||||
}
|
||||
}
|
15
nominatim/export.h
Normal file
15
nominatim/export.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef EXPORT_H
|
||||
#define EXPORT_H
|
||||
|
||||
#include <libxml/encoding.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void nominatim_export(int rank_min, int rank_max, const char *conninfo, const char *structuredoutputfile);
|
||||
void nominatim_exportCreatePreparedQueries(PGconn * conn);
|
||||
xmlTextWriterPtr nominatim_exportXMLStart(const char *structuredoutputfile);
|
||||
void nominatim_exportXMLEnd(xmlTextWriterPtr writer);
|
||||
void nominatim_exportPlace(uint64_t place_id, PGconn * conn, xmlTextWriterPtr writer, pthread_mutex_t * writer_mutex);
|
||||
const char * getRankLabel(int rank);
|
||||
|
||||
#endif
|
0
nominatim/geometry.cpp
Normal file
0
nominatim/geometry.cpp
Normal file
642
nominatim/import.c
Normal file
642
nominatim/import.c
Normal file
@ -0,0 +1,642 @@
|
||||
/*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#include <libxml/xmlstring.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/hash.h>
|
||||
|
||||
#include "nominatim.h"
|
||||
#include "import.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef enum { FILETYPE_NONE, FILETYPE_STRUCTUREDV0P1 } filetypes_t;
|
||||
typedef enum { FILEMODE_NONE, FILEMODE_ADD, FILEMODE_UPDATE, FILEMODE_DELETE } filemodes_t;
|
||||
|
||||
#define MAX_FEATUREADDRESS 500
|
||||
#define MAX_FEATURENAMES 1000
|
||||
|
||||
struct feature_address {
|
||||
int place_id;
|
||||
int rankAddress;
|
||||
xmlChar * type;
|
||||
xmlChar * id;
|
||||
xmlChar * key;
|
||||
xmlChar * value;
|
||||
xmlChar * distance;
|
||||
};
|
||||
|
||||
struct feature_name {
|
||||
xmlChar * type;
|
||||
xmlChar * value;
|
||||
};
|
||||
|
||||
struct feature {
|
||||
int placeID;
|
||||
xmlChar * type;
|
||||
xmlChar * id;
|
||||
xmlChar * key;
|
||||
xmlChar * value;
|
||||
xmlChar * rankAddress;
|
||||
xmlChar * rankSearch;
|
||||
xmlChar * countryCode;
|
||||
xmlChar * adminLevel;
|
||||
xmlChar * houseNumber;
|
||||
xmlChar * geometry;
|
||||
} feature;
|
||||
|
||||
int fileType = FILETYPE_NONE;
|
||||
int fileMode = FILEMODE_ADD;
|
||||
PGconn * conn;
|
||||
struct feature_address featureAddress[MAX_FEATUREADDRESS];
|
||||
struct feature_name featureName[MAX_FEATURENAMES];
|
||||
struct feature feature;
|
||||
int featureAddressLines = 0;
|
||||
int featureNameLines = 0;
|
||||
int featureCount = 0;
|
||||
xmlHashTablePtr partionTableTagsHash;
|
||||
|
||||
|
||||
|
||||
void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
{
|
||||
char * value;
|
||||
float version;
|
||||
int isAddressLine;
|
||||
|
||||
if (fileType == FILETYPE_NONE)
|
||||
{
|
||||
// Potential to handle other file types in the future / versions
|
||||
if (xmlStrEqual(name, BAD_CAST "osmStructured"))
|
||||
{
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "version");
|
||||
version = strtof(value, NULL);
|
||||
xmlFree(value);
|
||||
|
||||
if (version == (float)0.1)
|
||||
{
|
||||
fileType = FILETYPE_STRUCTUREDV0P1;
|
||||
fileMode = FILEMODE_ADD;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Unknown osmStructured version %f\n", version );
|
||||
exit_nicely();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Unknown XML document type: %s\n", name );
|
||||
exit_nicely();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "add"))
|
||||
{
|
||||
fileMode = FILEMODE_ADD;
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "update"))
|
||||
{
|
||||
fileMode = FILEMODE_UPDATE;
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "delete"))
|
||||
{
|
||||
fileMode = FILEMODE_DELETE;
|
||||
return;
|
||||
}
|
||||
if (fileMode == FILEMODE_NONE)
|
||||
{
|
||||
fprintf( stderr, "Unknown import mode in: %s\n", name );
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "feature"))
|
||||
{
|
||||
feature.type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
feature.id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
feature.key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
|
||||
feature.value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
|
||||
feature.rankAddress = xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
|
||||
feature.rankSearch = xmlTextReaderGetAttribute(reader, BAD_CAST "importance");
|
||||
|
||||
feature.countryCode = NULL;
|
||||
feature.adminLevel = NULL;
|
||||
feature.houseNumber = NULL;
|
||||
feature.geometry = NULL;
|
||||
featureAddressLines = 0;
|
||||
featureNameLines = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "names")) return;
|
||||
if (xmlStrEqual(name, BAD_CAST "name"))
|
||||
{
|
||||
featureName[featureNameLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureName[featureNameLines].value = xmlTextReaderReadString(reader);
|
||||
featureNameLines++;
|
||||
if (featureNameLines >= MAX_FEATURENAMES)
|
||||
{
|
||||
fprintf( stderr, "Too many name elements\n");
|
||||
exit_nicely();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "osmGeometry"))
|
||||
{
|
||||
feature.geometry = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "adminLevel"))
|
||||
{
|
||||
feature.adminLevel = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "countryCode"))
|
||||
{
|
||||
feature.countryCode = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "houseNumber"))
|
||||
{
|
||||
feature.houseNumber = xmlTextReaderReadString(reader);
|
||||
return;
|
||||
}
|
||||
if (xmlStrEqual(name, BAD_CAST "address"))
|
||||
{
|
||||
featureAddressLines = 0;
|
||||
return;
|
||||
}
|
||||
isAddressLine = 0;
|
||||
if (xmlStrEqual(name, BAD_CAST "continent"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "sea"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "country"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "state"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "county"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "city"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "town"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "village"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "unknown"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "suburb"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "postcode"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "neighborhood"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "street"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "access"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "building"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
else if (xmlStrEqual(name, BAD_CAST "other"))
|
||||
{
|
||||
isAddressLine = 1;
|
||||
}
|
||||
if (isAddressLine)
|
||||
{
|
||||
value = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "rank");
|
||||
if (!value)
|
||||
{
|
||||
fprintf( stderr, "Address element missing rank\n");
|
||||
exit_nicely();
|
||||
}
|
||||
featureAddress[featureAddressLines].rankAddress = atoi(value);
|
||||
xmlFree(value);
|
||||
|
||||
featureAddress[featureAddressLines].type = xmlTextReaderGetAttribute(reader, BAD_CAST "type");
|
||||
featureAddress[featureAddressLines].id = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
featureAddress[featureAddressLines].key = xmlTextReaderGetAttribute(reader, BAD_CAST "key");
|
||||
featureAddress[featureAddressLines].value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
|
||||
featureAddress[featureAddressLines].distance = xmlTextReaderGetAttribute(reader, BAD_CAST "distance");
|
||||
|
||||
featureAddressLines++;
|
||||
if (featureAddressLines >= MAX_FEATUREADDRESS)
|
||||
{
|
||||
fprintf( stderr, "Too many address elements\n");
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%s: Unknown element name: %s\n", __FUNCTION__, name);
|
||||
}
|
||||
|
||||
void EndElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
{
|
||||
PGresult * res;
|
||||
PGresult * resPlaceID;
|
||||
const char * paramValues[11];
|
||||
char * place_id;
|
||||
char * partionQueryName;
|
||||
int i;
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "feature"))
|
||||
{
|
||||
featureCount++;
|
||||
if (featureCount % 1000 == 0) printf("feature %i(k)\n", featureCount/1000);
|
||||
|
||||
if (fileMode == FILEMODE_ADD)
|
||||
{
|
||||
resPlaceID = PQexecPrepared(conn, "get_new_place_id", 0, NULL, NULL, NULL, 0);
|
||||
if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "get_place_id: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaceID);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paramValues[0] = (const char *)feature.type;
|
||||
paramValues[1] = (const char *)feature.id;
|
||||
paramValues[2] = (const char *)feature.key;
|
||||
paramValues[3] = (const char *)feature.value;
|
||||
resPlaceID = PQexecPrepared(conn, "get_new_place_id", 4, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaceID);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
place_id = PQgetvalue(resPlaceID, 0, 0);
|
||||
|
||||
if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_DELETE)
|
||||
{
|
||||
paramValues[0] = (const char *)place_id;
|
||||
res = PQexecPrepared(conn, "placex_delete", 1, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "placex_delete: DELETE failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
res = PQexecPrepared(conn, "search_name_delete", 1, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "search_name_delete: DELETE failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
res = PQexecPrepared(conn, "place_addressline_delete", 1, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "place_addressline_delete: DELETE failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_ADD)
|
||||
{
|
||||
// Insert into placex
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)feature.type;
|
||||
paramValues[2] = (const char *)feature.id;
|
||||
paramValues[3] = (const char *)feature.key;
|
||||
paramValues[4] = (const char *)feature.value;
|
||||
// paramValues[5] = (const char *)feature.name;
|
||||
paramValues[6] = (const char *)feature.adminLevel;
|
||||
paramValues[7] = (const char *)feature.houseNumber;
|
||||
paramValues[8] = (const char *)feature.rankAddress;
|
||||
paramValues[9] = (const char *)feature.rankSearch;
|
||||
paramValues[10] = (const char *)feature.geometry;
|
||||
res = PQexecPrepared(conn, "placex_insert", 11, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
for(i = 0; i < featureAddressLines; i++)
|
||||
{
|
||||
// insert into place_address
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)featureAddress[i].distance;
|
||||
paramValues[2] = (const char *)featureAddress[i].type;
|
||||
paramValues[3] = (const char *)featureAddress[i].id;
|
||||
paramValues[4] = (const char *)featureAddress[i].key;
|
||||
paramValues[5] = (const char *)featureAddress[i].value;
|
||||
res = PQexecPrepared(conn, "place_addressline_insert", 6, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "place_addressline_insert: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
xmlFree(featureAddress[i].type);
|
||||
xmlFree(featureAddress[i].id);
|
||||
xmlFree(featureAddress[i].key);
|
||||
xmlFree(featureAddress[i].value);
|
||||
xmlFree(featureAddress[i].distance);
|
||||
}
|
||||
|
||||
if (featureNameLines)
|
||||
{
|
||||
paramValues[0] = (const char *)place_id;
|
||||
res = PQexecPrepared(conn, "search_name_insert", 1, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "search_name_insert: INSERT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
partionQueryName = xmlHashLookup2(partionTableTagsHash, feature.key, feature.value);
|
||||
if (partionQueryName)
|
||||
{
|
||||
// insert into partition table
|
||||
paramValues[0] = (const char *)place_id;
|
||||
paramValues[1] = (const char *)feature.geometry;
|
||||
res = PQexecPrepared(conn, partionQueryName, 2, paramValues, NULL, NULL, 0);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "%s: INSERT failed: %s", partionQueryName, PQerrorMessage(conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < featureAddressLines; i++)
|
||||
{
|
||||
xmlFree(featureAddress[i].type);
|
||||
xmlFree(featureAddress[i].id);
|
||||
xmlFree(featureAddress[i].key);
|
||||
xmlFree(featureAddress[i].value);
|
||||
xmlFree(featureAddress[i].distance);
|
||||
}
|
||||
}
|
||||
|
||||
xmlFree(feature.type);
|
||||
xmlFree(feature.id);
|
||||
xmlFree(feature.key);
|
||||
xmlFree(feature.value);
|
||||
xmlFree(feature.rankAddress);
|
||||
xmlFree(feature.rankSearch);
|
||||
// if (feature.name) xmlFree(feature.name);
|
||||
if (feature.countryCode) xmlFree(feature.countryCode);
|
||||
if (feature.adminLevel) xmlFree(feature.adminLevel);
|
||||
if (feature.houseNumber) xmlFree(feature.houseNumber);
|
||||
if (feature.geometry) xmlFree(feature.geometry);
|
||||
|
||||
PQclear(resPlaceID);
|
||||
}
|
||||
}
|
||||
|
||||
static void processNode(xmlTextReaderPtr reader)
|
||||
{
|
||||
xmlChar *name;
|
||||
name = xmlTextReaderName(reader);
|
||||
if (name == NULL)
|
||||
{
|
||||
name = xmlStrdup(BAD_CAST "--");
|
||||
}
|
||||
|
||||
switch(xmlTextReaderNodeType(reader))
|
||||
{
|
||||
case XML_READER_TYPE_ELEMENT:
|
||||
StartElement(reader, name);
|
||||
if (xmlTextReaderIsEmptyElement(reader))
|
||||
EndElement(reader, name); /* No end_element for self closing tags! */
|
||||
break;
|
||||
case XML_READER_TYPE_END_ELEMENT:
|
||||
EndElement(reader, name);
|
||||
break;
|
||||
case XML_READER_TYPE_TEXT:
|
||||
case XML_READER_TYPE_CDATA:
|
||||
case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
|
||||
/* Ignore */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown node type %d\n", xmlTextReaderNodeType(reader));
|
||||
break;
|
||||
}
|
||||
|
||||
xmlFree(name);
|
||||
}
|
||||
|
||||
int nominatim_import(const char *conninfo, const char *partionTagsFilename, const char *filename)
|
||||
{
|
||||
xmlTextReaderPtr reader;
|
||||
int ret = 0;
|
||||
PGresult * res;
|
||||
FILE * partionTagsFile;
|
||||
char * partionQueryName;
|
||||
char partionQuerySQL[1024];
|
||||
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK)
|
||||
{
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
partionTableTagsHash = xmlHashCreate(200);
|
||||
|
||||
partionTagsFile = fopen(partionTagsFilename, "rt");
|
||||
if (!partionTagsFile)
|
||||
{
|
||||
fprintf(stderr, "Unable to read partition tags file: %s\n", partionTagsFilename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char buffer[1024], osmkey[256], osmvalue[256];
|
||||
int fields;
|
||||
while(fgets(buffer, sizeof(buffer), partionTagsFile) != NULL)
|
||||
{
|
||||
fields = sscanf( buffer, "%23s %63s", osmkey, osmvalue );
|
||||
|
||||
if( fields <= 0 ) continue;
|
||||
|
||||
if( fields != 2 )
|
||||
{
|
||||
fprintf( stderr, "Error partition file\n");
|
||||
exit_nicely();
|
||||
}
|
||||
partionQueryName = malloc(strlen("partition_insert_")+strlen(osmkey)+strlen(osmvalue)+2);
|
||||
strcpy(partionQueryName, "partition_insert_");
|
||||
strcat(partionQueryName, osmkey);
|
||||
strcat(partionQueryName, "_");
|
||||
strcat(partionQueryName, osmvalue);
|
||||
|
||||
strcpy(partionQuerySQL, "insert into place_classtype_");
|
||||
strcat(partionQuerySQL, osmkey);
|
||||
strcat(partionQuerySQL, "_");
|
||||
strcat(partionQuerySQL, osmvalue);
|
||||
strcat(partionQuerySQL, " (place_id, centroid) values ($1, ST_Centroid(st_setsrid($2, 4326)))");
|
||||
|
||||
res = PQprepare(conn, partionQueryName, partionQuerySQL, 2, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
xmlHashAddEntry2(partionTableTagsHash, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "get_new_place_id",
|
||||
"select nextval('seq_place')",
|
||||
0, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare get_new_place_id: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "get_place_id",
|
||||
"select place_id from placex where osm_type = $1 and osm_id = $2 and class = $3 and type = $4",
|
||||
4, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare get_place_id: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "placex_insert",
|
||||
"insert into placex (place_id,osm_type,osm_id,class,type,name,admin_level,housenumber,rank_address,rank_search,geometry) "
|
||||
"values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, st_setsrid($11, 4326))",
|
||||
11, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare placex_insert: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "search_name_insert",
|
||||
"insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) "
|
||||
"select place_id, rank_address, rank_search, country_code, make_keywords(name), "
|
||||
"(select uniq(sort(array_agg(name_vector))) from place_addressline join search_name on "
|
||||
"(address_place_id = search_name.place_id) where place_addressline.place_id = $1 ), st_centroid(geometry) from placex "
|
||||
"where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare placex_insert: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "place_addressline_insert",
|
||||
"insert into place_addressline (place_id, address_place_id, fromarea, isaddress, distance, cached_rank_address) "
|
||||
"select $1, place_id, false, true, $2, rank_address from placex where osm_type = $3 and osm_id = $4 and class = $5 and type = $6",
|
||||
6, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare place_addressline_insert: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "placex_delete",
|
||||
"delete from placex where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare placex_delete: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "search_name_delete",
|
||||
"delete from search_name where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare search_name_delete: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = PQprepare(conn, "place_addressline_delete",
|
||||
"delete from place_addressline where place_id = $1",
|
||||
1, NULL);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to prepare place_addressline_delete: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
featureCount = 0;
|
||||
|
||||
reader = inputUTF8(filename);
|
||||
|
||||
if (reader == NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to open %s\n", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = xmlTextReaderRead(reader);
|
||||
while (ret == 1)
|
||||
{
|
||||
processNode(reader);
|
||||
ret = xmlTextReaderRead(reader);
|
||||
}
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s : failed to parse\n", filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmlFreeTextReader(reader);
|
||||
xmlHashFree(partionTableTagsHash, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
6
nominatim/import.h
Normal file
6
nominatim/import.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef IMPORT_H
|
||||
#define IMPORT_H
|
||||
|
||||
int nominatim_import(const char *conninfo, const char *partionTagsFilename, const char *filename);
|
||||
|
||||
#endif
|
277
nominatim/index.c
Normal file
277
nominatim/index.c
Normal file
@ -0,0 +1,277 @@
|
||||
/*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#include "nominatim.h"
|
||||
#include "index.h"
|
||||
#include "export.h"
|
||||
#include "postgresql.h"
|
||||
|
||||
extern int verbose;
|
||||
|
||||
void nominatim_index(int rank_min, int rank_max, int num_threads, const char *conninfo, const char *structuredoutputfile)
|
||||
{
|
||||
struct index_thread_data * thread_data;
|
||||
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int tuples, count, sleepcount;
|
||||
|
||||
time_t rankStartTime;
|
||||
int rankTotalTuples;
|
||||
int rankCountTuples;
|
||||
float rankPerSecond;
|
||||
|
||||
PGconn *conn;
|
||||
PGresult * res;
|
||||
PGresult * resSectors;
|
||||
PGresult * resPlaces;
|
||||
|
||||
int rank;
|
||||
int i;
|
||||
int iSector;
|
||||
|
||||
const char *paramValues[2];
|
||||
int paramLengths[2];
|
||||
int paramFormats[2];
|
||||
uint32_t paramRank;
|
||||
uint32_t paramSector;
|
||||
uint32_t sector;
|
||||
|
||||
xmlTextWriterPtr writer;
|
||||
pthread_mutex_t writer_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
Oid pg_prepare_params[2];
|
||||
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK) {
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sectors",
|
||||
"select geometry_sector,count(*) from placex where rank_search = $1 and indexed = false and name is not null group by geometry_sector order by geometry_sector",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT4;
|
||||
pg_prepare_params[1] = PG_OID_INT4;
|
||||
res = PQprepare(conn, "index_sector_places",
|
||||
"select place_id from placex where rank_search = $1 and geometry_index(geometry,indexed,name) = $2",
|
||||
2, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
// Build the data for each thread
|
||||
thread_data = (struct index_thread_data *)malloc(sizeof(struct index_thread_data)*num_threads);
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
thread_data[i].conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(thread_data[i].conn) != CONNECTION_OK) {
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(thread_data[i].conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pg_prepare_params[0] = PG_OID_INT8;
|
||||
res = PQprepare(thread_data[i].conn, "index_placex",
|
||||
"update placex set indexed = true where place_id = $1",
|
||||
1, pg_prepare_params);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK) exit(EXIT_FAILURE);
|
||||
PQclear(res);
|
||||
|
||||
nominatim_exportCreatePreparedQueries(thread_data[i].conn);
|
||||
}
|
||||
|
||||
// Create the output file
|
||||
writer = NULL;
|
||||
if (structuredoutputfile)
|
||||
{
|
||||
writer = nominatim_exportXMLStart(structuredoutputfile);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Starting indexing rank (%i > %i ) using %i treads\n", rank_min, rank_max, num_threads);
|
||||
|
||||
for (rank = rank_min; rank <= rank_max; rank++)
|
||||
{
|
||||
printf("Starting rank %d\n", rank);
|
||||
rankStartTime = time(0);
|
||||
rankCountTuples = 0;
|
||||
rankPerSecond = 0;
|
||||
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
resSectors = PQexecPrepared(conn, "index_sectors", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resSectors) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sectors: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 0) != PG_OID_INT4)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resSectors, 1) != PG_OID_INT8)
|
||||
{
|
||||
fprintf(stderr, "Sector value has unexpected type\n");
|
||||
PQclear(resSectors);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rankTotalTuples = 0;
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
rankTotalTuples += PGint64(*((uint64_t *)PQgetvalue(resSectors, iSector, 1)));
|
||||
}
|
||||
|
||||
for (iSector = 0; iSector < PQntuples(resSectors); iSector++)
|
||||
{
|
||||
sector = PGint32(*((uint32_t *)PQgetvalue(resSectors, iSector, 0)));
|
||||
//printf("\n Starting sector %d size %ld\n", sector, PGint64(*((uint64_t *)PQgetvalue(resSectors, iSector, 1))));
|
||||
|
||||
// Get all the place_id's for this sector
|
||||
paramRank = PGint32(rank);
|
||||
paramValues[0] = (char *)¶mRank;
|
||||
paramLengths[0] = sizeof(paramRank);
|
||||
paramFormats[0] = 1;
|
||||
paramSector = PGint32(sector);
|
||||
paramValues[1] = (char *)¶mSector;
|
||||
paramLengths[1] = sizeof(paramSector);
|
||||
paramFormats[1] = 1;
|
||||
resPlaces = PQexecPrepared(conn, "index_sector_places", 2, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(resPlaces) != PGRES_TUPLES_OK)
|
||||
{
|
||||
fprintf(stderr, "index_sector_places: SELECT failed: %s", PQerrorMessage(conn));
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (PQftype(resPlaces, 0) != PG_OID_INT8)
|
||||
{
|
||||
fprintf(stderr, "Place_id value has unexpected type\n");
|
||||
PQclear(resPlaces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
rankPerSecond = 0;
|
||||
tuples = PQntuples(resPlaces);
|
||||
|
||||
if (tuples > 0)
|
||||
{
|
||||
// Spawn threads
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
thread_data[i].res = resPlaces;
|
||||
thread_data[i].tuples = tuples;
|
||||
thread_data[i].count = &count;
|
||||
thread_data[i].count_mutex = &count_mutex;
|
||||
thread_data[i].writer = writer;
|
||||
thread_data[i].writer_mutex = &writer_mutex;
|
||||
pthread_create(&thread_data[i].thread, NULL, &nominatim_indexThread, (void *)&thread_data[i]);
|
||||
}
|
||||
|
||||
// Monitor threads to give user feedback
|
||||
sleepcount = 0;
|
||||
while(count < tuples)
|
||||
{
|
||||
usleep(1000);
|
||||
|
||||
// Aim for one update per second
|
||||
if (sleepcount++ > 500)
|
||||
{
|
||||
rankPerSecond = ((float)rankCountTuples + (float)count) / MAX(difftime(time(0), rankStartTime),1);
|
||||
printf(" Done %i in %i @ %f per second - Rank %i ETA (seconds): %f\n", (rankCountTuples + count), (int)(difftime(time(0), rankStartTime)), rankPerSecond, rank, ((float)(rankTotalTuples - (rankCountTuples + count)))/rankPerSecond);
|
||||
sleepcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for everything to finish
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
pthread_join(thread_data[i].thread, NULL);
|
||||
}
|
||||
|
||||
rankCountTuples += tuples;
|
||||
}
|
||||
|
||||
// Finished sector
|
||||
rankPerSecond = (float)rankCountTuples / MAX(difftime(time(0), rankStartTime),1);
|
||||
printf(" Done %i in %i @ %f per second - ETA (seconds): %f\n", rankCountTuples, (int)(difftime(time(0), rankStartTime)), rankPerSecond, ((float)(rankTotalTuples - rankCountTuples))/rankPerSecond);
|
||||
|
||||
PQclear(resPlaces);
|
||||
|
||||
}
|
||||
// Finished rank
|
||||
printf("\r Done %i in %i @ %f per second - FINISHED \n\n", rankCountTuples, (int)(difftime(time(0), rankStartTime)), rankPerSecond);
|
||||
|
||||
PQclear(resSectors);
|
||||
}
|
||||
|
||||
if (writer)
|
||||
{
|
||||
nominatim_exportXMLEnd(writer);
|
||||
}
|
||||
}
|
||||
|
||||
void *nominatim_indexThread(void * thread_data_in)
|
||||
{
|
||||
struct index_thread_data * thread_data = (struct index_thread_data * )thread_data_in;
|
||||
|
||||
PGresult * res;
|
||||
|
||||
const char *paramValues[1];
|
||||
int paramLengths[1];
|
||||
int paramFormats[1];
|
||||
uint64_t paramPlaceID;
|
||||
uint64_t place_id;
|
||||
|
||||
while(1)
|
||||
{
|
||||
pthread_mutex_lock( thread_data->count_mutex );
|
||||
if (*(thread_data->count) >= thread_data->tuples)
|
||||
{
|
||||
pthread_mutex_unlock( thread_data->count_mutex );
|
||||
break;
|
||||
}
|
||||
|
||||
place_id = PGint64(*((uint64_t *)PQgetvalue(thread_data->res, *thread_data->count, 0)));
|
||||
(*thread_data->count)++;
|
||||
|
||||
pthread_mutex_unlock( thread_data->count_mutex );
|
||||
|
||||
//printf(" Processing place_id %ld\n", place_id);
|
||||
paramPlaceID = PGint64(place_id);
|
||||
paramValues[0] = (char *)¶mPlaceID;
|
||||
paramLengths[0] = sizeof(paramPlaceID);
|
||||
paramFormats[0] = 1;
|
||||
res = PQexecPrepared(thread_data->conn, "index_placex", 1, paramValues, paramLengths, paramFormats, 1);
|
||||
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "index_placex: UPDATE failed: %s", PQerrorMessage(thread_data->conn));
|
||||
PQclear(res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
if (thread_data->writer)
|
||||
{
|
||||
nominatim_exportPlace(place_id, thread_data->conn, thread_data->writer, thread_data->writer_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
20
nominatim/index.h
Normal file
20
nominatim/index.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef INDEX_H
|
||||
#define INDEX_H
|
||||
|
||||
#include <libxml/encoding.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
|
||||
struct index_thread_data{
|
||||
pthread_t thread;
|
||||
PGconn * conn;
|
||||
PGresult * res;
|
||||
int tuples;
|
||||
int * count;
|
||||
pthread_mutex_t * count_mutex;
|
||||
xmlTextWriterPtr writer;
|
||||
pthread_mutex_t * writer_mutex;
|
||||
};
|
||||
void nominatim_index(int rank_min, int rank_max, int num_threads, const char *conninfo, const char *structuredoutputfile);
|
||||
void *nominatim_indexThread(void * thread_data_in);
|
||||
|
||||
#endif
|
220
nominatim/input.c
Normal file
220
nominatim/input.c
Normal file
@ -0,0 +1,220 @@
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#define _LARGEFILE64_SOURCE
|
||||
|
||||
#ifdef __MINGW_H
|
||||
# include <windows.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <bzlib.h>
|
||||
|
||||
#include "input.h"
|
||||
|
||||
struct Input {
|
||||
char *name;
|
||||
enum { plainFile, gzipFile, bzip2File } type;
|
||||
void *fileHandle;
|
||||
// needed by bzip2 when decompressing from multiple streams. other
|
||||
// decompressors must ignore it.
|
||||
FILE *systemHandle;
|
||||
int eof;
|
||||
char buf[4096];
|
||||
int buf_ptr, buf_fill;
|
||||
};
|
||||
|
||||
// tries to re-open the bz stream at the next stream start.
|
||||
// returns 0 on success, -1 on failure.
|
||||
int bzReOpen(struct Input *ctx, int *error) {
|
||||
// for copying out the last unused part of the block which
|
||||
// has an EOS token in it. needed for re-initialising the
|
||||
// next stream.
|
||||
unsigned char unused[BZ_MAX_UNUSED];
|
||||
void *unused_tmp_ptr = NULL;
|
||||
int nUnused, i;
|
||||
|
||||
BZ2_bzReadGetUnused(error, (BZFILE *)(ctx->fileHandle), &unused_tmp_ptr, &nUnused);
|
||||
if (*error != BZ_OK) return -1;
|
||||
|
||||
// when bzReadClose is called the unused buffer is deallocated,
|
||||
// so it needs to be copied somewhere safe first.
|
||||
for (i = 0; i < nUnused; ++i)
|
||||
unused[i] = ((unsigned char *)unused_tmp_ptr)[i];
|
||||
|
||||
BZ2_bzReadClose(error, (BZFILE *)(ctx->fileHandle));
|
||||
if (*error != BZ_OK) return -1;
|
||||
|
||||
// reassign the file handle
|
||||
ctx->fileHandle = BZ2_bzReadOpen(error, ctx->systemHandle, 0, 0, unused, nUnused);
|
||||
if (ctx->fileHandle == NULL || *error != BZ_OK) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int readFile(void *context, char * buffer, int len)
|
||||
{
|
||||
struct Input *ctx = context;
|
||||
void *f = ctx->fileHandle;
|
||||
int l = 0, error = 0;
|
||||
|
||||
if (ctx->eof || (len == 0))
|
||||
return 0;
|
||||
|
||||
switch(ctx->type) {
|
||||
case plainFile:
|
||||
l = read(*(int *)f, buffer, len);
|
||||
if (l <= 0) ctx->eof = 1;
|
||||
break;
|
||||
case gzipFile:
|
||||
l = gzread((gzFile)f, buffer, len);
|
||||
if (l <= 0) ctx->eof = 1;
|
||||
break;
|
||||
case bzip2File:
|
||||
l = BZ2_bzRead(&error, (BZFILE *)f, buffer, len);
|
||||
|
||||
// error codes BZ_OK and BZ_STREAM_END are both "OK", but the stream
|
||||
// end means the reader needs to be reset from the original handle.
|
||||
if (error != BZ_OK) {
|
||||
// for stream errors, try re-opening the stream before admitting defeat.
|
||||
if (error != BZ_STREAM_END || bzReOpen(ctx, &error) != 0) {
|
||||
l = 0;
|
||||
ctx->eof = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad file type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (l < 0) {
|
||||
fprintf(stderr, "File reader received error %d (%d)\n", l, error);
|
||||
l = 0;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
char inputGetChar(void *context)
|
||||
{
|
||||
struct Input *ctx = context;
|
||||
|
||||
if (ctx->buf_ptr == ctx->buf_fill) {
|
||||
ctx->buf_fill = readFile(context, &ctx->buf[0], sizeof(ctx->buf));
|
||||
ctx->buf_ptr = 0;
|
||||
if (ctx->buf_fill == 0)
|
||||
return 0;
|
||||
if (ctx->buf_fill < 0) {
|
||||
perror("Error while reading file");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
//readFile(context, &c, 1);
|
||||
return ctx->buf[ctx->buf_ptr++];
|
||||
}
|
||||
|
||||
int inputEof(void *context)
|
||||
{
|
||||
return ((struct Input *)context)->eof;
|
||||
}
|
||||
|
||||
void *inputOpen(const char *name)
|
||||
{
|
||||
const char *ext = strrchr(name, '.');
|
||||
struct Input *ctx = malloc (sizeof(*ctx));
|
||||
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->name = strdup(name);
|
||||
|
||||
if (ext && !strcmp(ext, ".gz")) {
|
||||
ctx->fileHandle = (void *)gzopen(name, "rb");
|
||||
ctx->type = gzipFile;
|
||||
} else if (ext && !strcmp(ext, ".bz2")) {
|
||||
int error = 0;
|
||||
ctx->systemHandle = fopen(name, "rb");
|
||||
if (!ctx->systemHandle) {
|
||||
fprintf(stderr, "error while opening file %s\n", name);
|
||||
exit(10);
|
||||
}
|
||||
|
||||
ctx->fileHandle = (void *)BZ2_bzReadOpen(&error, ctx->systemHandle, 0, 0, NULL, 0);
|
||||
ctx->type = bzip2File;
|
||||
|
||||
} else {
|
||||
int *pfd = malloc(sizeof(pfd));
|
||||
if (pfd) {
|
||||
if (!strcmp(name, "-")) {
|
||||
*pfd = STDIN_FILENO;
|
||||
} else {
|
||||
int flags = O_RDONLY;
|
||||
#ifdef O_LARGEFILE
|
||||
flags |= O_LARGEFILE;
|
||||
#endif
|
||||
*pfd = open(name, flags);
|
||||
if (*pfd < 0) {
|
||||
free(pfd);
|
||||
pfd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->fileHandle = (void *)pfd;
|
||||
ctx->type = plainFile;
|
||||
}
|
||||
if (!ctx->fileHandle) {
|
||||
fprintf(stderr, "error while opening file %s\n", name);
|
||||
exit(10);
|
||||
}
|
||||
ctx->buf_ptr = 0;
|
||||
ctx->buf_fill = 0;
|
||||
return (void *)ctx;
|
||||
}
|
||||
|
||||
int inputClose(void *context)
|
||||
{
|
||||
struct Input *ctx = context;
|
||||
void *f = ctx->fileHandle;
|
||||
|
||||
switch(ctx->type) {
|
||||
case plainFile:
|
||||
close(*(int *)f);
|
||||
free(f);
|
||||
break;
|
||||
case gzipFile:
|
||||
gzclose((gzFile)f);
|
||||
break;
|
||||
case bzip2File:
|
||||
BZ2_bzclose((BZFILE *)f);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad file type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
free(ctx->name);
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmlTextReaderPtr inputUTF8(const char *name)
|
||||
{
|
||||
void *ctx = inputOpen(name);
|
||||
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Input reader create failed for: %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xmlReaderForIO(readFile, inputClose, (void *)ctx, NULL, NULL, 0);
|
||||
}
|
11
nominatim/input.h
Normal file
11
nominatim/input.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
int readFile(void *context, char * buffer, int len);
|
||||
int inputClose(void *context);
|
||||
void *inputOpen(const char *name);
|
||||
char inputGetChar(void *context);
|
||||
int inputEof(void *context);
|
||||
xmlTextReaderPtr inputUTF8(const char *name);
|
||||
|
||||
#endif
|
17
nominatim/nominatim-svn.sh
Executable file
17
nominatim/nominatim-svn.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
DATE=$(date +%Y%m%d)
|
||||
MODULE="$(basename $0 -svn.sh)"
|
||||
SVNROOT=http://svn.openstreetmap.org/applications/utils/nominatim/
|
||||
|
||||
set -x
|
||||
rm -rf $MODULE
|
||||
|
||||
svn export $SVNROOT $MODULE/
|
||||
|
||||
## tar it up
|
||||
tar cjf $MODULE-${DATE}svn.tar.bz2 $MODULE
|
||||
|
||||
## cleanup
|
||||
rm -rf $MODULE
|
||||
|
210
nominatim/nominatim.c
Normal file
210
nominatim/nominatim.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
#-----------------------------------------------------------------------------
|
||||
# nominatim - [description]
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright 2010, Brian Quinion
|
||||
# Based on osm2pgsql
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#include "nominatim.h"
|
||||
#include "postgresql.h"
|
||||
#include "sprompt.h"
|
||||
#include "index.h"
|
||||
#include "export.h"
|
||||
#include "import.h"
|
||||
|
||||
int verbose;
|
||||
|
||||
void exit_nicely(void)
|
||||
{
|
||||
fprintf(stderr, "Error occurred, cleaning up\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void short_usage(char *arg0)
|
||||
{
|
||||
const char *name = basename(arg0);
|
||||
|
||||
fprintf(stderr, "Usage error. For further information see:\n");
|
||||
fprintf(stderr, "\t%s -h|--help\n", name);
|
||||
}
|
||||
|
||||
static void long_usage(char *arg0)
|
||||
{
|
||||
const char *name = basename(arg0);
|
||||
|
||||
fprintf(stderr, "Usage:\n");
|
||||
fprintf(stderr, "\t%s [options] planet.osms\n", name);
|
||||
fprintf(stderr, "\nThis will import the structured osm data into a PostgreSQL database\n");
|
||||
fprintf(stderr, "suitable for nominatim search engine\n");
|
||||
fprintf(stderr, "\nOptions:\n");
|
||||
fprintf(stderr, " -d|--database\tThe name of the PostgreSQL database to connect\n");
|
||||
fprintf(stderr, " \tto (default: nominatim).\n");
|
||||
fprintf(stderr, " -U|--username\tPostgresql user name.\n");
|
||||
fprintf(stderr, " -W|--password\tForce password prompt.\n");
|
||||
fprintf(stderr, " -H|--host\t\tDatabase server hostname or socket location.\n");
|
||||
fprintf(stderr, " -P|--port\t\tDatabase server port.\n");
|
||||
fprintf(stderr, " -i|--index\t\tIndex the database.\n");
|
||||
fprintf(stderr, " -e|--export\t\tGenerate a structured file.\n");
|
||||
fprintf(stderr, " -I|--import\t\tImport a structured file.\n");
|
||||
fprintf(stderr, " -t|--threads\t\tNumber of threads to create for indexing.\n");
|
||||
fprintf(stderr, " -F|--file\t\tfile to use (either to import or export).\n");
|
||||
fprintf(stderr, " -T|--tagfile\t\tfile containing 'special' tag pairs\n");
|
||||
fprintf(stderr, " \t(default: partitionedtags.def).\n");
|
||||
fprintf(stderr, " -h|--help\t\tHelp information.\n");
|
||||
fprintf(stderr, " -v|--verbose\t\tVerbose output.\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (sizeof(int*) == 4) {
|
||||
fprintf(stderr, "\n\nYou are running this on 32bit system - this will not work\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int long_usage_bool=0;
|
||||
int pass_prompt=0;
|
||||
const char *db = "nominatim";
|
||||
const char *username=NULL;
|
||||
const char *host=NULL;
|
||||
const char *password=NULL;
|
||||
const char *port = "5432";
|
||||
const char *conninfo = NULL;
|
||||
int index = 0;
|
||||
int export = 0;
|
||||
int import = 0;
|
||||
int threads = 1;
|
||||
const char *file = NULL;
|
||||
const char *tagsfile = "partitionedtags.def";
|
||||
|
||||
//import = 1;
|
||||
//structuredinputfile = "out.osms";
|
||||
|
||||
PGconn *conn;
|
||||
|
||||
fprintf(stderr, "nominatim SVN version %s\n\n", VERSION);
|
||||
|
||||
if (sizeof(int*) == 4) {
|
||||
fprintf(stderr, "\n!! You are running this on 32bit system, so at most\n");
|
||||
fprintf(stderr, "!! 3GB of RAM can be used. If you encounter unexpected\n");
|
||||
fprintf(stderr, "!! exceptions during import, you should try running in slim\n");
|
||||
fprintf(stderr, "!! mode using parameter -s.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int c, option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
|
||||
{"verbose", 0, 0, 'v'},
|
||||
|
||||
{"database", 1, 0, 'd'},
|
||||
{"username", 1, 0, 'U'},
|
||||
{"password", 0, 0, 'W'},
|
||||
{"host", 1, 0, 'H'},
|
||||
{"port", 1, 0, 'P'},
|
||||
|
||||
{"index", 0, 0, 'i'},
|
||||
{"export", 0, 0, 'e'},
|
||||
{"import", 1, 0, 'I'},
|
||||
{"threads", 1, 0, 't'},
|
||||
{"file", 1, 0, 'F'},
|
||||
{"tagsfile", 1, 0, 'T'},
|
||||
|
||||
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "vhd:U:WH:P:ieIt:F:T:", long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'v': verbose=1; break;
|
||||
case 'd': db=optarg; break;
|
||||
case 'U': username=optarg; break;
|
||||
case 'W': pass_prompt=1; break;
|
||||
case 'H': host=optarg; break;
|
||||
case 'P': port=optarg; break;
|
||||
case 'h': long_usage_bool=1; break;
|
||||
case 'i': index=1; break;
|
||||
case 'e': export=1; break;
|
||||
case 'I': import=1; break;
|
||||
case 't': threads=atoi(optarg); break;
|
||||
case 'F': file=optarg; break;
|
||||
case 'T': tagsfile=optarg; break;
|
||||
case '?':
|
||||
default:
|
||||
short_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (long_usage_bool) {
|
||||
long_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (threads < 1) threads = 1;
|
||||
|
||||
/*
|
||||
if (argc == optind) { // No non-switch arguments
|
||||
short_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*/
|
||||
if (index && import) {
|
||||
fprintf(stderr, "Error: --index and --import options can not be used on the same database!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (pass_prompt)
|
||||
password = simple_prompt("Password:", 100, 0);
|
||||
else {
|
||||
password = getenv("PGPASS");
|
||||
}
|
||||
|
||||
// Test the database connection
|
||||
conninfo = build_conninfo(db, username, password, host, port);
|
||||
conn = PQconnectdb(conninfo);
|
||||
if (PQstatus(conn) != CONNECTION_OK) {
|
||||
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
PQfinish(conn);
|
||||
|
||||
if (index) nominatim_index(0, 30, threads, conninfo, file);
|
||||
if (export) nominatim_export(0, 30, conninfo, file);
|
||||
if (import) nominatim_import(conninfo, tagsfile, file);
|
||||
|
||||
return 0;
|
||||
}
|
30
nominatim/nominatim.h
Normal file
30
nominatim/nominatim.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef NOMINATIM_H
|
||||
#define NOMINATIM_H
|
||||
|
||||
#define MAX(x,y) (x > y?x:y)
|
||||
#define MIN(x,y) (x < y?x:y)
|
||||
|
||||
struct output_options {
|
||||
const char *conninfo; /* Connection info string */
|
||||
const char *prefix; /* prefix for table names */
|
||||
int scale; /* scale for converting coordinates to fixed point */
|
||||
int projection; /* SRS of projection */
|
||||
int append; /* Append to existing data */
|
||||
int slim; /* In slim mode */
|
||||
int cache; /* Memory usable for cache in MB */
|
||||
struct middle_t *mid; /* Mid storage to use */
|
||||
const char *tblsindex; /* Pg Tablespace to store indexes */
|
||||
const char *style; /* style file to use */
|
||||
int expire_tiles_zoom; /* Zoom level for tile expiry list */
|
||||
int expire_tiles_zoom_min; /* Minimum zoom level for tile expiry list */
|
||||
const char *expire_tiles_filename; /* File name to output expired tiles list to */
|
||||
int enable_hstore; /* add an additional hstore column with objects key/value pairs */
|
||||
int enable_multi; /* Output multi-geometries intead of several simple geometries */
|
||||
char** hstore_columns; /* list of columns that should be written into their own hstore column */
|
||||
int n_hstore_columns; /* number of hstore columns */
|
||||
};
|
||||
|
||||
void exit_nicely(void);
|
||||
void short_usage(char *arg0);
|
||||
|
||||
#endif
|
55
nominatim/nominatim.spec.in
Normal file
55
nominatim/nominatim.spec.in
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
%define svn @SVN@
|
||||
|
||||
Summary: Nominatim OpenStreetMap geocoding database
|
||||
Name: @PACKAGE@
|
||||
Group: Applications/Text
|
||||
Version: @VERSION@
|
||||
Release: 1.%{svn}%{?dist}
|
||||
|
||||
License: GPL
|
||||
URL: http://svn.openstreetmap.org/applications/utils/nominatim
|
||||
Source0: %{name}-%{version}-%{svn}.tar.bz2
|
||||
Source1: nominatim-svn.sh
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
BuildRequires: geos-devel
|
||||
BuildRequires: libxml2-devel
|
||||
BuildRequires: postgresql-devel
|
||||
BuildRequires: bzip2-devel
|
||||
BuildRequires: proj-devel
|
||||
|
||||
%description
|
||||
Processes data imported using osm2pgsql from the communtiy mapping project
|
||||
at http://www.openstreetmap.org.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}
|
||||
|
||||
|
||||
%build
|
||||
|
||||
export CFLAGS="$RPM_OPT_FLAGS"
|
||||
export CXXFLAGS="$RPM_OPT_FLAGS"
|
||||
|
||||
make all
|
||||
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
install -D -p nominatim $RPM_BUILD_ROOT/usr/bin/nominatim
|
||||
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc README.txt
|
||||
%{_bindir}/nominatim
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Sep 09 2010 Brian Quinion <nominatim@brian.quinion.co.uk> 0.1-1.20070316svn
|
||||
- Initial build
|
2
nominatim/partitionedtags.def
Normal file
2
nominatim/partitionedtags.def
Normal file
@ -0,0 +1,2 @@
|
||||
amenity pub
|
||||
amenity hotel
|
37
nominatim/postgresql.c
Normal file
37
nominatim/postgresql.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "postgresql.h"
|
||||
|
||||
const char *build_conninfo(const char *db, const char *username, const char *password, const char *host, const char *port)
|
||||
{
|
||||
static char conninfo[1024];
|
||||
|
||||
conninfo[0]='\0';
|
||||
strcat(conninfo, "dbname='");
|
||||
strcat(conninfo, db);
|
||||
strcat(conninfo, "'");
|
||||
|
||||
if (username) {
|
||||
strcat(conninfo, " user='");
|
||||
strcat(conninfo, username);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
if (password) {
|
||||
strcat(conninfo, " password='");
|
||||
strcat(conninfo, password);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
if (host) {
|
||||
strcat(conninfo, " host='");
|
||||
strcat(conninfo, host);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
if (port) {
|
||||
strcat(conninfo, " port='");
|
||||
strcat(conninfo, port);
|
||||
strcat(conninfo, "'");
|
||||
}
|
||||
|
||||
return conninfo;
|
||||
}
|
22
nominatim/postgresql.h
Normal file
22
nominatim/postgresql.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
*/
|
||||
|
||||
#ifndef POSTGRESQL_H
|
||||
#define POSTGRESQL_H
|
||||
|
||||
#define PG_OID_INT8 20
|
||||
#define PG_OID_INT4 23
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define PGint16(x) (x)
|
||||
#define PGint32(x) (x)
|
||||
#define PGint64(x) (x)
|
||||
#else
|
||||
#define PGint16(x) __bswap_16 (x)
|
||||
#define PGint32(x) __bswap_32 (x)
|
||||
#define PGint64(x) __bswap_64 (x)
|
||||
#endif
|
||||
|
||||
const char *build_conninfo(const char *db, const char *username, const char *password, const char *host, const char *port);
|
||||
|
||||
#endif
|
199
nominatim/sprompt.c
Normal file
199
nominatim/sprompt.c
Normal file
@ -0,0 +1,199 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* sprompt.c
|
||||
* simple_prompt() routine
|
||||
*
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/port/sprompt.c,v 1.18 2006/10/04 00:30:14 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* PostgreSQL Database Management System
|
||||
* (formerly known as Postgres, then as Postgres95)
|
||||
*
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
*
|
||||
* Portions Copyright (c) 1994, The Regents of the University of California
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose, without fee, and without a written agreement
|
||||
* is hereby granted, provided that the above copyright notice and this
|
||||
* paragraph and the following two paragraphs appear in all copies.
|
||||
*
|
||||
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
|
||||
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
|
||||
* DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* simple_prompt
|
||||
*
|
||||
* Generalized function especially intended for reading in usernames and
|
||||
* password interactively. Reads from /dev/tty or stdin/stderr.
|
||||
*
|
||||
* prompt: The prompt to print
|
||||
* maxlen: How many characters to accept
|
||||
* echo: Set to false if you want to hide what is entered (for passwords)
|
||||
*
|
||||
* Returns a malloc()'ed string with the input (w/o trailing newline).
|
||||
*/
|
||||
|
||||
#define DEVTTY "/dev/tty"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#ifdef __MINGW_H
|
||||
# include <windows.h>
|
||||
#else
|
||||
# define HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
extern char *simple_prompt(const char *prompt, int maxlen, int echo);
|
||||
*/
|
||||
|
||||
char *
|
||||
simple_prompt(const char *prompt, int maxlen, int echo)
|
||||
{
|
||||
int length;
|
||||
char *destination;
|
||||
FILE *termin,
|
||||
*termout;
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios t_orig,
|
||||
t;
|
||||
#else
|
||||
#ifdef WIN32
|
||||
HANDLE t = NULL;
|
||||
LPDWORD t_orig = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
destination = (char *) malloc(maxlen + 1);
|
||||
if (!destination)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Do not try to collapse these into one "w+" mode file. Doesn't work on
|
||||
* some platforms (eg, HPUX 10.20).
|
||||
*/
|
||||
termin = fopen(DEVTTY, "r");
|
||||
termout = fopen(DEVTTY, "w");
|
||||
if (!termin || !termout
|
||||
#ifdef WIN32
|
||||
/* See DEVTTY comment for msys */
|
||||
|| (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (termin)
|
||||
fclose(termin);
|
||||
if (termout)
|
||||
fclose(termout);
|
||||
termin = stdin;
|
||||
termout = stderr;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
if (!echo)
|
||||
{
|
||||
tcgetattr(fileno(termin), &t);
|
||||
t_orig = t;
|
||||
t.c_lflag &= ~ECHO;
|
||||
tcsetattr(fileno(termin), TCSAFLUSH, &t);
|
||||
}
|
||||
#else
|
||||
#ifdef WIN32
|
||||
if (!echo)
|
||||
{
|
||||
/* get a new handle to turn echo off */
|
||||
t_orig = (LPDWORD) malloc(sizeof(DWORD));
|
||||
t = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
/* save the old configuration first */
|
||||
GetConsoleMode(t, t_orig);
|
||||
|
||||
/* set to the new mode */
|
||||
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (prompt)
|
||||
{
|
||||
fputs(prompt, termout);
|
||||
fflush(termout);
|
||||
}
|
||||
|
||||
if (fgets(destination, maxlen + 1, termin) == NULL)
|
||||
destination[0] = '\0';
|
||||
|
||||
length = strlen(destination);
|
||||
if (length > 0 && destination[length - 1] != '\n')
|
||||
{
|
||||
/* eat rest of the line */
|
||||
char buf[128];
|
||||
int buflen;
|
||||
|
||||
do
|
||||
{
|
||||
if (fgets(buf, sizeof(buf), termin) == NULL)
|
||||
break;
|
||||
buflen = strlen(buf);
|
||||
} while (buflen > 0 && buf[buflen - 1] != '\n');
|
||||
}
|
||||
|
||||
if (length > 0 && destination[length - 1] == '\n')
|
||||
/* remove trailing newline */
|
||||
destination[length - 1] = '\0';
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
if (!echo)
|
||||
{
|
||||
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
|
||||
fputs("\n", termout);
|
||||
fflush(termout);
|
||||
}
|
||||
#else
|
||||
#ifdef WIN32
|
||||
if (!echo)
|
||||
{
|
||||
/* reset to the original console mode */
|
||||
SetConsoleMode(t, *t_orig);
|
||||
fputs("\n", termout);
|
||||
fflush(termout);
|
||||
free(t_orig);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (termin != stdin)
|
||||
{
|
||||
fclose(termin);
|
||||
fclose(termout);
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
4
nominatim/sprompt.h
Normal file
4
nominatim/sprompt.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef SPROMPT_H
|
||||
#define SPROMPT_H
|
||||
char *simple_prompt(const char *prompt, int maxlen, int echo);
|
||||
#endif
|
23
settings/settings.php
Normal file
23
settings/settings.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
// General settings
|
||||
@define('CONST_Debug', false);
|
||||
@define('CONST_Database_DSN', 'pgsql://@/nominatim');
|
||||
|
||||
// Website settings
|
||||
@define('CONST_ClosedForIndexing', false);
|
||||
@define('CONST_ClosedForIndexingExceptionIPs', '');
|
||||
@define('CONST_BlockedIPs', '');
|
||||
|
||||
@define('CONST_Website_BaseURL', 'http://'.php_uname('n').'/');
|
||||
|
||||
@define('CONST_Default_Language', 'xx');
|
||||
@define('CONST_Default_Lat', 20.0);
|
||||
@define('CONST_Default_Lon', 0.0);
|
||||
@define('CONST_Default_Zoom', 2);
|
||||
|
||||
@define('CONST_Search_AreaPolygons_Enabled', true);
|
||||
|
||||
@define('CONST_Suggestions_Enabled', false);
|
||||
|
||||
|
2516
sql/functions.sql
Normal file
2516
sql/functions.sql
Normal file
File diff suppressed because it is too large
Load Diff
13
sql/loaddata.sql
Normal file
13
sql/loaddata.sql
Normal file
@ -0,0 +1,13 @@
|
||||
TRUNCATE placex;
|
||||
TRUNCATE search_name;
|
||||
TRUNCATE place_addressline;
|
||||
TRUNCATE location_area;
|
||||
|
||||
DROP SEQUENCE seq_place;
|
||||
CREATE SEQUENCE seq_place start 100000;
|
||||
|
||||
insert into placex (osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, country_code, geometry) select * from place where osm_type = 'N';
|
||||
insert into placex (osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, country_code, geometry) select * from place where osm_type = 'W';
|
||||
insert into placex (osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, country_code, geometry) select * from place where osm_type = 'R';
|
||||
|
||||
--select count(*) from (select create_interpolation(osm_id, housenumber) from placex where indexed=false and class='place' and type='houses') as x;
|
149
sql/partitions.src.sql
Normal file
149
sql/partitions.src.sql
Normal file
@ -0,0 +1,149 @@
|
||||
create type nearplace as (
|
||||
place_id bigint
|
||||
);
|
||||
|
||||
create type nearfeature as (
|
||||
place_id bigint,
|
||||
keywords int[],
|
||||
rank_address integer,
|
||||
rank_search integer,
|
||||
distance float
|
||||
);
|
||||
|
||||
-- start
|
||||
CREATE TABLE location_area_large_-partition- () INHERITS (location_area_large);
|
||||
CREATE INDEX idx_location_area_large_-partition-_geometry ON location_area_large_-partition- USING GIST (geometry);
|
||||
|
||||
CREATE TABLE location_area_roadnear_-partition- () INHERITS (location_area_roadnear);
|
||||
CREATE INDEX idx_location_area_roadnear_-partition-_geometry ON location_area_roadnear_-partition- USING GIST (geometry);
|
||||
|
||||
CREATE TABLE location_area_roadfar_-partition- () INHERITS (location_area_roadfar);
|
||||
CREATE INDEX idx_location_area_roadfar_-partition-_geometry ON location_area_roadfar_-partition- USING GIST (geometry);
|
||||
-- end
|
||||
|
||||
create or replace function getNearRoads(in_partition TEXT, point GEOMETRY) RETURNS setof nearplace AS $$
|
||||
DECLARE
|
||||
r nearplace%rowtype;
|
||||
BEGIN
|
||||
|
||||
-- start
|
||||
IF in_partition = '-partition-' THEN
|
||||
FOR r IN SELECT place_id FROM location_area_large WHERE partition = '-partition-' and ST_Contains(geometry, point) LOOP
|
||||
RETURN NEXT r;
|
||||
END LOOP;
|
||||
RETURN;
|
||||
END IF;
|
||||
-- end
|
||||
|
||||
RAISE EXCEPTION 'Unknown partition %', in_partition;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
create or replace function getNearFeatures(in_partition TEXT, point GEOMETRY, maxrank INTEGER) RETURNS setof nearfeature AS $$
|
||||
DECLARE
|
||||
r nearfeature%rowtype;
|
||||
BEGIN
|
||||
|
||||
-- start
|
||||
IF in_partition = '-partition-' THEN
|
||||
FOR r IN SELECT
|
||||
place_id,
|
||||
keywords,
|
||||
rank_address,
|
||||
rank_search,
|
||||
ST_Distance(place_centroid, centroid) as distance
|
||||
FROM location_area_large
|
||||
WHERE ST_Contains(area, point) and location_area_large.rank_search < maxrank
|
||||
ORDER BY ST_Distance(place_centroid, centroid) ASC
|
||||
LOOP
|
||||
RETURN NEXT r;
|
||||
END LOOP;
|
||||
RETURN;
|
||||
END IF;
|
||||
-- end
|
||||
|
||||
RAISE EXCEPTION 'Unknown partition %', in_partition;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
create or replace function deleteLocationArea(in_partition TEXT, in_place_id bigint) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
|
||||
-- start
|
||||
IF in_partition = '-partition-' THEN
|
||||
DELETE from location_area_large_-partition- WHERE place_id = in_place_id;
|
||||
DELETE from location_area_roadnear_-partition- WHERE place_id = in_place_id;
|
||||
DELETE from location_area_roadfar_-partition- WHERE place_id = in_place_id;
|
||||
RETURN TRUE;
|
||||
END IF;
|
||||
-- end
|
||||
|
||||
RAISE EXCEPTION 'Unknown partition %', in_partition;
|
||||
|
||||
RETURN FALSE;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
create or replace function insertLocationAreaLarge(
|
||||
in_partition TEXT, in_place_id bigint, in_keywords INTEGER[],
|
||||
in_rank_search INTEGER, in_rank_address INTEGER, in_estimate BOOLEAN,
|
||||
in_centroid GEOMETRY, in_geometry GEOMETRY) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
|
||||
-- start
|
||||
IF in_partition = '-partition-' THEN
|
||||
INSERT INTO location_area_large_-partition- values (in_partition, in_place_id, in_keywords, in_rank_search, in_rank_address, in_estimate, in_centroid, in_geometry);
|
||||
RETURN TRUE;
|
||||
END IF;
|
||||
-- end
|
||||
|
||||
RAISE EXCEPTION 'Unknown partition %', in_partition;
|
||||
RETURN FALSE;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
create or replace function insertLocationAreaRoadNear(
|
||||
in_partition TEXT, in_place_id bigint, in_keywords INTEGER[],
|
||||
in_rank_search INTEGER, in_rank_address INTEGER, in_estimate BOOLEAN,
|
||||
in_centroid GEOMETRY, in_geometry GEOMETRY) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
|
||||
-- start
|
||||
IF in_partition = '-partition-' THEN
|
||||
INSERT INTO location_area_roadnear_-partition- values (in_partition, in_place_id, in_keywords, in_rank_search, in_rank_address, in_estimate, in_centroid, in_geometry);
|
||||
RETURN TRUE;
|
||||
END IF;
|
||||
-- end
|
||||
|
||||
RAISE EXCEPTION 'Unknown partition %', in_partition;
|
||||
RETURN FALSE;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
create or replace function insertLocationAreaRoadFar(
|
||||
in_partition TEXT, in_place_id bigint, in_keywords INTEGER[],
|
||||
in_rank_search INTEGER, in_rank_address INTEGER, in_estimate BOOLEAN,
|
||||
in_centroid GEOMETRY, in_geometry GEOMETRY) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
|
||||
-- start
|
||||
IF in_partition = '-partition-' THEN
|
||||
INSERT INTO location_area_roadfar_-partition- values (in_partition, in_place_id, in_keywords, in_rank_search, in_rank_address, in_estimate, in_centroid, in_geometry);
|
||||
RETURN TRUE;
|
||||
END IF;
|
||||
-- end
|
||||
|
||||
RAISE EXCEPTION 'Unknown partition %', in_partition;
|
||||
RETURN FALSE;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
269
sql/tables.sql
Normal file
269
sql/tables.sql
Normal file
@ -0,0 +1,269 @@
|
||||
drop table import_status;
|
||||
CREATE TABLE import_status (
|
||||
lastimportdate timestamp NOT NULL
|
||||
);
|
||||
GRANT SELECT ON import_status TO "www-data" ;
|
||||
|
||||
drop table import_osmosis_log;
|
||||
CREATE TABLE import_osmosis_log (
|
||||
batchend timestamp,
|
||||
batchsize integer,
|
||||
starttime timestamp,
|
||||
endtime timestamp,
|
||||
event text
|
||||
);
|
||||
|
||||
--drop table IF EXISTS query_log;
|
||||
CREATE TABLE query_log (
|
||||
starttime timestamp,
|
||||
query text,
|
||||
ipaddress text,
|
||||
endtime timestamp,
|
||||
results integer
|
||||
);
|
||||
CREATE INDEX idx_query_log ON query_log USING BTREE (starttime);
|
||||
GRANT INSERT ON query_log TO "www-data" ;
|
||||
|
||||
CREATE TABLE new_query_log (
|
||||
type text,
|
||||
starttime timestamp,
|
||||
ipaddress text,
|
||||
useragent text,
|
||||
language text,
|
||||
query text,
|
||||
endtime timestamp,
|
||||
results integer,
|
||||
format text,
|
||||
secret text
|
||||
);
|
||||
CREATE INDEX idx_new_query_log_starttime ON new_query_log USING BTREE (starttime);
|
||||
GRANT INSERT ON new_query_log TO "www-data" ;
|
||||
GRANT UPDATE ON new_query_log TO "www-data" ;
|
||||
GRANT SELECT ON new_query_log TO "www-data" ;
|
||||
|
||||
create view vw_search_query_log as SELECT substr(query, 1, 50) AS query, starttime, endtime - starttime AS duration, substr(useragent, 1, 20) as
|
||||
useragent, language, results, ipaddress FROM new_query_log WHERE type = 'search' ORDER BY starttime DESC;
|
||||
|
||||
--drop table IF EXISTS report_log;
|
||||
CREATE TABLE report_log (
|
||||
starttime timestamp,
|
||||
ipaddress text,
|
||||
query text,
|
||||
description text,
|
||||
email text
|
||||
);
|
||||
GRANT INSERT ON report_log TO "www-data" ;
|
||||
|
||||
drop table IF EXISTS word;
|
||||
CREATE TABLE word (
|
||||
word_id INTEGER,
|
||||
word_token text,
|
||||
word_trigram text,
|
||||
word text,
|
||||
class text,
|
||||
type text,
|
||||
country_code varchar(2),
|
||||
search_name_count INTEGER
|
||||
);
|
||||
SELECT AddGeometryColumn('word', 'location', 4326, 'GEOMETRY', 2);
|
||||
CREATE INDEX idx_word_word_id on word USING BTREE (word_id);
|
||||
CREATE INDEX idx_word_word_token on word USING BTREE (word_token);
|
||||
CREATE INDEX idx_word_trigram ON word USING gin(word_trigram gin_trgm_ops);
|
||||
GRANT SELECT ON word TO "www-data" ;
|
||||
DROP SEQUENCE seq_word;
|
||||
CREATE SEQUENCE seq_word start 1;
|
||||
|
||||
drop table IF EXISTS location_area CASCADE;
|
||||
CREATE TABLE location_area (
|
||||
partition varchar(10),
|
||||
place_id bigint,
|
||||
keywords INTEGER[],
|
||||
rank_search INTEGER NOT NULL,
|
||||
rank_address INTEGER NOT NULL,
|
||||
isguess BOOL
|
||||
);
|
||||
SELECT AddGeometryColumn('location_area', 'centroid', 4326, 'POINT', 2);
|
||||
SELECT AddGeometryColumn('location_area', 'geometry', 4326, 'GEOMETRY', 2);
|
||||
|
||||
CREATE TABLE location_area_large () INHERITS (location_area);
|
||||
CREATE TABLE location_area_roadnear () INHERITS (location_area);
|
||||
CREATE TABLE location_area_roadfar () INHERITS (location_area);
|
||||
|
||||
drop table IF EXISTS search_name;
|
||||
CREATE TABLE search_name (
|
||||
place_id bigint,
|
||||
search_rank integer,
|
||||
address_rank integer,
|
||||
country_code varchar(2),
|
||||
name_vector integer[],
|
||||
nameaddress_vector integer[]
|
||||
);
|
||||
CREATE INDEX search_name_name_vector_idx ON search_name USING GIN (name_vector gin__int_ops);
|
||||
CREATE INDEX searchnameplacesearch_search_nameaddress_vector_idx ON search_name USING GIN (nameaddress_vector gin__int_ops);
|
||||
SELECT AddGeometryColumn('search_name', 'centroid', 4326, 'GEOMETRY', 2);
|
||||
CREATE INDEX idx_search_name_centroid ON search_name USING GIST (centroid);
|
||||
CREATE INDEX idx_search_name_place_id ON search_name USING BTREE (place_id);
|
||||
|
||||
drop table IF EXISTS place_addressline;
|
||||
CREATE TABLE place_addressline (
|
||||
place_id bigint,
|
||||
address_place_id bigint,
|
||||
fromarea boolean,
|
||||
isaddress boolean,
|
||||
distance float,
|
||||
cached_rank_address integer
|
||||
);
|
||||
CREATE INDEX idx_place_addressline_place_id on place_addressline USING BTREE (place_id);
|
||||
CREATE INDEX idx_place_addressline_address_place_id on place_addressline USING BTREE (address_place_id);
|
||||
|
||||
drop table IF EXISTS place_boundingbox CASCADE;
|
||||
CREATE TABLE place_boundingbox (
|
||||
place_id bigint,
|
||||
minlat float,
|
||||
maxlat float,
|
||||
minlon float,
|
||||
maxlon float,
|
||||
numfeatures integer,
|
||||
area float
|
||||
);
|
||||
CREATE INDEX idx_place_boundingbox_place_id on place_boundingbox USING BTREE (place_id);
|
||||
SELECT AddGeometryColumn('place_boundingbox', 'outline', 4326, 'GEOMETRY', 2);
|
||||
CREATE INDEX idx_place_boundingbox_outline ON place_boundingbox USING GIST (outline);
|
||||
GRANT SELECT on place_boundingbox to "www-data" ;
|
||||
GRANT INSERT on place_boundingbox to "www-data" ;
|
||||
|
||||
drop table IF EXISTS reverse_cache;
|
||||
CREATE TABLE reverse_cache (
|
||||
latlonzoomid integer,
|
||||
country_code varchar(2),
|
||||
place_id bigint
|
||||
);
|
||||
GRANT SELECT on reverse_cache to "www-data" ;
|
||||
GRANT INSERT on reverse_cache to "www-data" ;
|
||||
CREATE INDEX idx_reverse_cache_latlonzoomid ON reverse_cache USING BTREE (latlonzoomid);
|
||||
|
||||
drop table country;
|
||||
CREATE TABLE country (
|
||||
country_code varchar(2),
|
||||
country_name hstore,
|
||||
country_default_language_code varchar(2)
|
||||
);
|
||||
SELECT AddGeometryColumn('country', 'geometry', 4326, 'POLYGON', 2);
|
||||
insert into country select iso3166::varchar(2), ARRAY[ROW('name:en',cntry_name)::keyvalue], null,
|
||||
ST_Transform(geometryn(the_geom, generate_series(1, numgeometries(the_geom))), 4326) from worldboundaries;
|
||||
CREATE INDEX idx_country_country_code ON country USING BTREE (country_code);
|
||||
CREATE INDEX idx_country_geometry ON country USING GIST (geometry);
|
||||
|
||||
drop table placex;
|
||||
CREATE TABLE placex (
|
||||
place_id bigint NOT NULL,
|
||||
partition varchar(10),
|
||||
osm_type char(1),
|
||||
osm_id bigint,
|
||||
class TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
name HSTORE,
|
||||
admin_level integer,
|
||||
housenumber TEXT,
|
||||
street TEXT,
|
||||
isin TEXT,
|
||||
postcode TEXT,
|
||||
country_code varchar(2),
|
||||
street_place_id bigint,
|
||||
rank_address INTEGER,
|
||||
rank_search INTEGER,
|
||||
indexed_status INTEGER,
|
||||
indexed_date TIMESTAMP,
|
||||
geometry_sector INTEGER
|
||||
);
|
||||
SELECT AddGeometryColumn('placex', 'geometry', 4326, 'GEOMETRY', 2);
|
||||
CREATE UNIQUE INDEX idx_place_id ON placex USING BTREE (place_id);
|
||||
CREATE INDEX idx_placex_osmid ON placex USING BTREE (osm_type, osm_id);
|
||||
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search);
|
||||
CREATE INDEX idx_placex_rank_address ON placex USING BTREE (rank_address);
|
||||
CREATE INDEX idx_placex_geometry ON placex USING GIST (geometry);
|
||||
CREATE INDEX idx_placex_indexed ON placex USING BTREE (indexed);
|
||||
CREATE INDEX idx_placex_pending ON placex USING BTREE (rank_search) where name IS NOT NULL and indexed = false;
|
||||
CREATE INDEX idx_placex_pendingbylatlon ON placex USING BTREE (geometry_index(geometry_sector,indexed,name),rank_search)
|
||||
where geometry_index(geometry_sector,indexed,name) IS NOT NULL;
|
||||
CREATE INDEX idx_placex_street_place_id ON placex USING BTREE (street_place_id) where street_place_id IS NOT NULL;
|
||||
CREATE INDEX idx_placex_gb_postcodesector ON placex USING BTREE (substring(upper(postcode) from '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])[A-Z][A-Z]$'))
|
||||
where country_code = 'gb' and substring(upper(postcode) from '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])[A-Z][A-Z]$') is not null;
|
||||
CREATE INDEX idx_placex_interpolation ON placex USING BTREE (geometry_sector) where indexed = false and class='place' and type='houses';
|
||||
CREATE INDEX idx_placex_sector ON placex USING BTREE (geometry_sector,rank_address,osm_type,osm_id);
|
||||
CLUSTER placex USING idx_placex_sector;
|
||||
|
||||
DROP SEQUENCE seq_place;
|
||||
CREATE SEQUENCE seq_place start 1;
|
||||
GRANT SELECT on placex to "www-data" ;
|
||||
GRANT UPDATE ON placex to "www-data" ;
|
||||
GRANT SELECT ON search_name to "www-data" ;
|
||||
GRANT DELETE on search_name to "www-data" ;
|
||||
GRANT INSERT on search_name to "www-data" ;
|
||||
GRANT SELECT on place_addressline to "www-data" ;
|
||||
GRANT INSERT ON place_addressline to "www-data" ;
|
||||
GRANT DELETE on place_addressline to "www-data" ;
|
||||
GRANT SELECT on location_point to "www-data" ;
|
||||
GRANT SELECT ON seq_word to "www-data" ;
|
||||
GRANT UPDATE ON seq_word to "www-data" ;
|
||||
GRANT INSERT ON word to "www-data" ;
|
||||
GRANT SELECT ON planet_osm_ways to "www-data" ;
|
||||
GRANT SELECT ON planet_osm_rels to "www-data" ;
|
||||
GRANT SELECT on location_point to "www-data" ;
|
||||
GRANT SELECT on location_area to "www-data" ;
|
||||
GRANT SELECT on location_point_26 to "www-data" ;
|
||||
GRANT SELECT on location_point_25 to "www-data" ;
|
||||
GRANT SELECT on location_point_24 to "www-data" ;
|
||||
GRANT SELECT on location_point_23 to "www-data" ;
|
||||
GRANT SELECT on location_point_22 to "www-data" ;
|
||||
GRANT SELECT on location_point_21 to "www-data" ;
|
||||
GRANT SELECT on location_point_20 to "www-data" ;
|
||||
GRANT SELECT on location_point_19 to "www-data" ;
|
||||
GRANT SELECT on location_point_18 to "www-data" ;
|
||||
GRANT SELECT on location_point_17 to "www-data" ;
|
||||
GRANT SELECT on location_point_16 to "www-data" ;
|
||||
GRANT SELECT on location_point_15 to "www-data" ;
|
||||
GRANT SELECT on location_point_14 to "www-data" ;
|
||||
GRANT SELECT on location_point_13 to "www-data" ;
|
||||
GRANT SELECT on location_point_12 to "www-data" ;
|
||||
GRANT SELECT on location_point_11 to "www-data" ;
|
||||
GRANT SELECT on location_point_10 to "www-data" ;
|
||||
GRANT SELECT on location_point_9 to "www-data" ;
|
||||
GRANT SELECT on location_point_8 to "www-data" ;
|
||||
GRANT SELECT on location_point_7 to "www-data" ;
|
||||
GRANT SELECT on location_point_6 to "www-data" ;
|
||||
GRANT SELECT on location_point_5 to "www-data" ;
|
||||
GRANT SELECT on location_point_4 to "www-data" ;
|
||||
GRANT SELECT on location_point_3 to "www-data" ;
|
||||
GRANT SELECT on location_point_2 to "www-data" ;
|
||||
GRANT SELECT on location_point_1 to "www-data" ;
|
||||
GRANT SELECT on country to "www-data" ;
|
||||
|
||||
-- insert creates the location tagbles, creates location indexes if indexed == true
|
||||
CREATE TRIGGER placex_before_insert BEFORE INSERT ON placex
|
||||
FOR EACH ROW EXECUTE PROCEDURE placex_insert();
|
||||
|
||||
-- update insert creates the location tables
|
||||
CREATE TRIGGER placex_before_update BEFORE UPDATE ON placex
|
||||
FOR EACH ROW EXECUTE PROCEDURE placex_update();
|
||||
|
||||
-- diff update triggers
|
||||
CREATE TRIGGER placex_before_delete AFTER DELETE ON placex
|
||||
FOR EACH ROW EXECUTE PROCEDURE placex_delete();
|
||||
CREATE TRIGGER place_before_delete BEFORE DELETE ON place
|
||||
FOR EACH ROW EXECUTE PROCEDURE place_delete();
|
||||
CREATE TRIGGER place_before_insert BEFORE INSERT ON place
|
||||
FOR EACH ROW EXECUTE PROCEDURE place_insert();
|
||||
|
||||
alter table placex add column geometry_sector INTEGER;
|
||||
alter table placex add column indexed_status INTEGER;
|
||||
alter table placex add column indexed_date TIMESTAMP;
|
||||
|
||||
update placex set geometry_sector = geometry_sector(geometry);
|
||||
drop index idx_placex_pendingbylatlon;
|
||||
drop index idx_placex_interpolation;
|
||||
drop index idx_placex_sector;
|
||||
CREATE INDEX idx_placex_pendingbylatlon ON placex USING BTREE (geometry_index(geometry_sector,indexed,name),rank_search)
|
||||
where geometry_index(geometry_sector,indexed,name) IS NOT NULL;
|
||||
CREATE INDEX idx_placex_interpolation ON placex USING BTREE (geometry_sector) where indexed = false and class='place' and type='houses';
|
||||
CREATE INDEX idx_placex_sector ON placex USING BTREE (geometry_sector,rank_address,osm_type,osm_id);
|
37
utils/setup.php
Executable file
37
utils/setup.php
Executable file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/php -Cq
|
||||
<?php
|
||||
|
||||
require_once('../lib/init-cmd.php');
|
||||
ini_set('memory_limit', '800M');
|
||||
|
||||
$aCMDOptions = array(
|
||||
"Create and setup nominatim search system",
|
||||
array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
|
||||
array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
|
||||
array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
|
||||
|
||||
array('create-partitions', '', 0, 1, 0, 0, 'bool', 'Create required partition tables and triggers'),
|
||||
);
|
||||
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
|
||||
|
||||
if ($aCMDResult['create-partitions'])
|
||||
{
|
||||
$sSQL = 'select distinct country_code from country_name order by country_code';
|
||||
$aPartitions = $oDB->getCol($sSQL);
|
||||
$aPartitions[] = 'none';
|
||||
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/partitions.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);
|
||||
}
|
||||
echo $sTemplate;
|
||||
}
|
||||
|
||||
showUsage($aCMDOptions, true);
|
Loading…
Reference in New Issue
Block a user