2010-11-01 18:46:28 +03:00
< ? php
2012-12-09 01:39:24 +04:00
@ define ( 'CONST_ConnectionBucket_PageType' , 'Reverse' );
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
2013-04-13 00:45:24 +04: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 ;
}
}
$oDB =& getDB ();
ini_set ( 'memory_limit' , '200M' );
// Format for output
$sOutputFormat = 'xml' ;
if ( isset ( $_GET [ 'format' ]) && ( $_GET [ 'format' ] == 'xml' || $_GET [ 'format' ] == 'json' || $_GET [ 'format' ] == 'jsonv2' ))
{
$sOutputFormat = $_GET [ 'format' ];
}
2010-11-01 18:46:28 +03:00
2011-03-18 12:52:16 +03:00
// Show address breakdown
$bShowAddressDetails = true ;
if ( isset ( $_GET [ 'addressdetails' ])) $bShowAddressDetails = ( bool ) $_GET [ 'addressdetails' ];
2013-04-13 00:45:24 +04:00
// Preferred language
$aLangPrefOrder = getPreferredLanguages ();
$sLanguagePrefArraySQL = " ARRAY[ " . join ( ',' , array_map ( " getDBQuoted " , $aLangPrefOrder )) . " ] " ;
2010-11-01 18:46:28 +03:00
$hLog = logStart ( $oDB , 'reverse' , $_SERVER [ 'QUERY_STRING' ], $aLangPrefOrder );
2013-04-13 00:45:24 +04:00
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 ( $sSQL = ( " select place_id from placex where osm_type = ' " . $_GET [ 'osm_type' ] . " ' and osm_id = " . ( int ) $_GET [ 'osm_id' ] . " order by type = 'postcode' asc " ));
2013-02-07 22:39:33 +04:00
if ( CONST_Debug ) var_dump ( $sSQL );
2010-11-01 18:46:28 +03:00
if ( ! $iPlaceID ) $sError = 'OSM ID Not Found' ;
2013-04-13 00:45:24 +04:00
}
2010-11-01 18:46:28 +03:00
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 (
2013-04-13 00:45:24 +04:00
0 => 2 , // Continent / Sea
1 => 2 ,
2 => 2 ,
3 => 4 , // Country
4 => 4 ,
5 => 8 , // State
6 => 10 , // Region
7 => 10 ,
8 => 12 , // County
9 => 12 ,
10 => 17 , // City
11 => 17 ,
12 => 18 , // Town / Village
13 => 18 ,
14 => 22 , // Suburb
15 => 22 ,
16 => 26 , // Street, TODO: major street?
17 => 26 ,
18 => 30 , // or >, Building
19 => 30 , // or >, Building
);
2012-05-26 01:45:59 +04:00
$iMaxRank = ( isset ( $_GET [ 'zoom' ]) && isset ( $aZoomRank [ $_GET [ 'zoom' ]])) ? $aZoomRank [ $_GET [ 'zoom' ]] : 28 ;
2010-11-01 18:46:28 +03:00
// Find the nearest point
2013-02-12 22:10:36 +04:00
$fSearchDiam = 0.0004 ;
2010-11-01 18:46:28 +03:00
$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)' ;
2012-06-28 22:39:18 +04:00
$sSQL .= ' and class not in (\'waterway\',\'railway\',\'tunnel\',\'bridge\')' ;
2011-02-02 15:01:26 +03:00
$sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ' ;
2013-05-08 15:16:45 +04:00
$sSQL .= ' and indexed_status = 0 ' ;
2012-12-18 16:50:34 +04:00
$sSQL .= ' OR ST_DWithin(' . $sPointSQL . ', centroid, ' . $fSearchDiam . '))' ;
2011-02-02 15:01:26 +03:00
$sSQL .= ' ORDER BY ST_distance(' . $sPointSQL . ', geometry) ASC limit 1' ;
2013-02-07 22:39:33 +04:00
if ( CONST_Debug ) var_dump ( $sSQL );
2011-02-02 15:01:26 +03:00
$aPlace = $oDB -> getRow ( $sSQL );
2012-07-09 20:16:54 +04:00
if ( PEAR :: IsError ( $aPlace ))
2010-11-01 18:46:28 +03:00
{
2013-04-13 00:45:24 +04:00
failInternalError ( " Could not determine closest place. " , $sSQL , $iPlaceID );
2010-11-01 18:46:28 +03:00
}
2012-07-09 20:16:54 +04:00
$iPlaceID = $aPlace [ 'place_id' ];
$iParentPlaceID = $aPlace [ 'parent_place_id' ];
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
{
2013-04-13 00:45:24 +04:00
if ( $aPlace [ 'rank_search' ] > 28 && $iParentPlaceID )
{
2012-05-24 19:54:51 +04:00
$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
{
2013-04-13 00:45:24 +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.*, " ;
2013-04-13 00:45:24 +04:00
$sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL ) as langaddress, " ;
$sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL ) as placename, " ;
$sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref, " ;
$sSQL .= " st_y(centroid) as lat, st_x(centroid) as lon " ;
$sSQL .= " from placex where place_id = $iPlaceID " ;
2012-12-17 04:24:58 +04:00
2010-11-01 18:46:28 +03:00
$aPlace = $oDB -> getRow ( $sSQL );
2013-04-13 00:45:24 +04:00
//var_dump($sSQL, $aPlace); exit;
2010-11-01 18:46:28 +03:00
2011-03-18 12:52:16 +03:00
if ( $bShowAddressDetails )
{
2013-01-24 20:17:37 +04:00
$aAddress = getAddressDetails ( $oDB , $sLanguagePrefArraySQL , $iPlaceID , $aPlace [ 'calculated_country_code' ]);
2011-03-18 12:52:16 +03:00
}
2011-02-02 15:01:26 +03:00
$aClassType = getClassTypes ();
2012-05-26 01:45:59 +04:00
$sAddressType = '' ;
$sClassType = $aPlace [ 'class' ] . ':' . $aPlace [ 'type' ] . ':' . $aPlace [ 'admin_level' ];
if ( isset ( $aClassType [ $sClassType ]) && isset ( $aClassType [ $sClassType ][ 'simplelabel' ]))
{
$sAddressType = $aClassType [ $aClassType ][ 'simplelabel' ];
}
else
{
$sClassType = $aPlace [ 'class' ] . ':' . $aPlace [ 'type' ];
if ( isset ( $aClassType [ $sClassType ]) && isset ( $aClassType [ $sClassType ][ 'simplelabel' ]))
$sAddressType = $aClassType [ $sClassType ][ 'simplelabel' ];
else $sAddressType = $aPlace [ 'class' ];
}
$aPlace [ 'addresstype' ] = $sAddressType ;
2011-02-02 15:01:26 +03:00
2010-11-01 18:46:28 +03:00
}
2013-02-07 22:39:33 +04:00
if ( CONST_Debug ) exit ;
2011-02-02 15:01:26 +03:00
include ( CONST_BasePath . '/lib/template/address-' . $sOutputFormat . '.php' );