2010-11-01 18:46:28 +03:00
< ? php
2011-02-02 15:01:26 +03:00
require_once ( dirname ( dirname ( __FILE__ )) . '/lib/init-website.php' );
require_once ( CONST_BasePath . '/lib/log.php' );
2010-11-01 18:46:28 +03:00
if ( strpos ( CONST_BulkUserIPs , ',' . $_SERVER [ " REMOTE_ADDR " ] . ',' ) !== false )
{
$fLoadAvg = getLoadAverage ();
if ( $fLoadAvg > 2 ) sleep ( 60 );
if ( $fLoadAvg > 4 ) sleep ( 120 );
if ( $fLoadAvg > 6 )
{
echo " Bulk User: Temporary block due to high server load \n " ;
exit ;
}
}
2012-05-24 19:54:51 +04:00
$oDB =& getDB ();
2010-11-01 18:46:28 +03:00
ini_set ( 'memory_limit' , '200M' );
// Format for output
2012-05-24 19:54:51 +04:00
$sOutputFormat = 'xml' ;
2011-02-02 15:01:26 +03:00
if ( isset ( $_GET [ 'format' ]) && ( $_GET [ 'format' ] == 'xml' || $_GET [ 'format' ] == 'json' || $_GET [ 'format' ] == 'jsonv2' ))
2010-11-01 18:46:28 +03:00
{
$sOutputFormat = $_GET [ 'format' ];
}
2011-03-18 12:52:16 +03:00
// Show address breakdown
$bShowAddressDetails = true ;
if ( isset ( $_GET [ 'addressdetails' ])) $bShowAddressDetails = ( bool ) $_GET [ 'addressdetails' ];
2010-11-01 18:46:28 +03:00
// Prefered language
$aLangPrefOrder = getPrefferedLangauges ();
$sLanguagePrefArraySQL = " ARRAY[ " . join ( ',' , array_map ( " getDBQuoted " , $aLangPrefOrder )) . " ] " ;
$hLog = logStart ( $oDB , 'reverse' , $_SERVER [ 'QUERY_STRING' ], $aLangPrefOrder );
if ( isset ( $_GET [ 'osm_type' ]) && isset ( $_GET [ 'osm_id' ]) && ( int ) $_GET [ 'osm_id' ] && ( $_GET [ 'osm_type' ] == 'N' || $_GET [ 'osm_type' ] == 'W' || $_GET [ 'osm_type' ] == 'R' ))
{
$iPlaceID = $oDB -> getOne ( " select place_id from placex where osm_type = ' " . $_GET [ 'osm_type' ] . " ' and osm_id = " . ( int ) $_GET [ 'osm_id' ] . " order by type = 'postcode' asc " );
if ( ! $iPlaceID ) $sError = 'OSM ID Not Found' ;
}
else
{
// Location to look up
$fLat = ( float ) $_GET [ 'lat' ];
$fLon = ( float ) $_GET [ 'lon' ];
$sPointSQL = " ST_SetSRID(ST_Point( $fLon , $fLat ),4326) " ;
// Zoom to rank, this could probably be calculated but a lookup gives fine control
$aZoomRank = array (
0 => 2 , // Continent / Sea
1 => 2 ,
2 => 2 ,
3 => 4 , // Country
4 => 4 ,
5 => 8 , // State
6 => 10 , // Region
2012-05-24 19:54:51 +04:00
7 => 10 ,
2010-11-01 18:46:28 +03:00
8 => 12 , // County
2012-05-24 19:54:51 +04:00
9 => 12 ,
2010-11-01 18:46:28 +03:00
10 => 17 , // City
2012-05-24 19:54:51 +04:00
11 => 17 ,
2010-11-01 18:46:28 +03:00
12 => 18 , // Town / Village
2012-05-24 19:54:51 +04:00
13 => 18 ,
2010-11-01 18:46:28 +03:00
14 => 22 , // Suburb
15 => 22 ,
16 => 26 , // Street, TODO: major street?
2012-05-24 19:54:51 +04:00
17 => 26 ,
2011-02-02 15:01:26 +03:00
18 => 30 , // or >, Building
2010-11-01 18:46:28 +03:00
19 => 30 , // or >, Building
);
$iMaxRank = isset ( $aZoomRank [ $_GET [ 'zoom' ]]) ? $aZoomRank [ $_GET [ 'zoom' ]] : 28 ;
// Find the nearest point
$fSearchDiam = 0.0001 ;
$iPlaceID = null ;
$aArea = false ;
2011-02-22 23:01:26 +03:00
$fMaxAreaDistance = 1 ;
2010-11-01 18:46:28 +03:00
while ( ! $iPlaceID && $fSearchDiam < $fMaxAreaDistance )
{
$fSearchDiam = $fSearchDiam * 2 ;
// If we have to expand the search area by a large amount then we need a larger feature
// then there is a limit to how small the feature should be
if ( $fSearchDiam > 2 && $iMaxRank > 4 ) $iMaxRank = 4 ;
if ( $fSearchDiam > 1 && $iMaxRank > 9 ) $iMaxRank = 8 ;
if ( $fSearchDiam > 0.8 && $iMaxRank > 10 ) $iMaxRank = 10 ;
if ( $fSearchDiam > 0.6 && $iMaxRank > 12 ) $iMaxRank = 12 ;
if ( $fSearchDiam > 0.2 && $iMaxRank > 17 ) $iMaxRank = 17 ;
if ( $fSearchDiam > 0.1 && $iMaxRank > 18 ) $iMaxRank = 18 ;
2011-02-02 15:01:26 +03:00
if ( $fSearchDiam > 0.008 && $iMaxRank > 22 ) $iMaxRank = 22 ;
if ( $fSearchDiam > 0.001 && $iMaxRank > 26 ) $iMaxRank = 26 ;
2010-11-01 18:46:28 +03:00
2012-05-24 19:54:51 +04:00
$sSQL = 'select place_id,parent_place_id,rank_search from placex' ;
2011-02-02 15:01:26 +03:00
$sSQL .= ' WHERE ST_DWithin(' . $sPointSQL . ', geometry, ' . $fSearchDiam . ')' ;
$sSQL .= ' and rank_search != 28 and rank_search >= ' . $iMaxRank ;
$sSQL .= ' and (name is not null or housenumber is not null)' ;
$sSQL .= ' and class not in (\'waterway\')' ;
$sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ' ;
$sSQL .= ' OR ST_DWithin(' . $sPointSQL . ', ST_Centroid(geometry), ' . $fSearchDiam . '))' ;
$sSQL .= ' ORDER BY ST_distance(' . $sPointSQL . ', geometry) ASC limit 1' ;
//var_dump($sSQL);
$aPlace = $oDB -> getRow ( $sSQL );
$iPlaceID = $aPlace [ 'place_id' ];
2012-05-24 19:54:51 +04:00
$iParentPlaceID = $aPlace [ 'parent_place_id' ];
2011-02-02 15:01:26 +03:00
if ( PEAR :: IsError ( $iPlaceID ))
2010-11-01 18:46:28 +03:00
{
2012-03-18 20:58:19 +04:00
failInternalError ( " Could not determine closest place. " , $sSQL , $iPlaceID );
2010-11-01 18:46:28 +03:00
}
2011-02-02 15:01:26 +03:00
}
// The point we found might be too small - use the address to find what it is a child of
2012-05-24 19:54:51 +04:00
if ( $iPlaceID && $iMaxRank < 28 )
2011-02-02 15:01:26 +03:00
{
2012-05-24 19:54:51 +04:00
if ( $aPlace [ 'rank_search' ] > 28 && $iParentPlaceID ) {
$iPlaceID = $iParentPlaceID ;
}
$sSQL = " select address_place_id from place_addressline where place_id = $iPlaceID order by abs(cached_rank_address - $iMaxRank ) asc,cached_rank_address desc,isaddress desc,distance desc limit 1 " ;
2011-02-02 15:01:26 +03:00
$iPlaceID = $oDB -> getOne ( $sSQL );
if ( PEAR :: IsError ( $iPlaceID ))
2010-11-01 18:46:28 +03:00
{
2012-03-18 20:58:19 +04:00
failInternalError ( " Could not get parent for place. " , $sSQL , $iPlaceID );
2010-11-01 18:46:28 +03:00
}
2011-02-22 23:01:26 +03:00
if ( ! $iPlaceID )
{
$iPlaceID = $aPlace [ 'place_id' ];
}
2011-02-02 15:01:26 +03:00
}
2010-11-01 18:46:28 +03:00
}
if ( $iPlaceID )
{
$sSQL = " select placex.*, " ;
$sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL ) as langaddress, " ;
$sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL ) as placename, " ;
2011-04-07 19:57:57 +04:00
$sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref, " ;
$sSQL .= " st_y(st_centroid(geometry)) as lat, st_x(st_centroid(geometry)) as lon " ;
2010-11-01 18:46:28 +03:00
$sSQL .= " from placex where place_id = $iPlaceID " ;
2011-04-07 19:57:57 +04:00
//var_dump($sSQL);
2010-11-01 18:46:28 +03:00
$aPlace = $oDB -> getRow ( $sSQL );
2011-03-18 12:52:16 +03:00
if ( $bShowAddressDetails )
{
$aAddress = getAddressDetails ( $oDB , $sLanguagePrefArraySQL , $iPlaceID , $aPlace [ 'country_code' ]);
}
2011-02-02 15:01:26 +03:00
$aClassType = getClassTypes ();
$sAddressType = '' ;
if ( isset ( $aClassType [ $aPlace [ 'class' ] . ':' . $aPlace [ 'type' ] . ':' . $aPlace [ 'admin_level' ]]))
$sAddressType = $aClassType [ $aPlace [ 'class' ] . ':' . $aPlace [ 'type' ] . ':' . $aPlace [ 'admin_level' ]][ 'simplelabel' ];
elseif ( isset ( $aClassType [ $aPlace [ 'class' ] . ':' . $aPlace [ 'type' ]]))
$sAddressType = $aClassType [ $aPlace [ 'class' ] . ':' . $aPlace [ 'type' ]][ 'simplelabel' ];
else $sAddressType = $aPlace [ 'class' ];
$aPlace [ 'addresstype' ] = $sAddressType ;
2010-11-01 18:46:28 +03:00
}
2011-02-02 15:01:26 +03:00
include ( CONST_BasePath . '/lib/template/address-' . $sOutputFormat . '.php' );