声明:转载自废客论坛。本程序代码只供学习,不可用于非法途径!后果自负!!!

终于搞定地图经纬度偏移修正数据库,在网上下的google 0.01精度校正数据,共处理 9845988 条数据,总计耗时 120.116666667分钟,近千万级数据量,累死!看来还得用二分查找法。
(注:需要校正库的我只能提供精度为0.1修正数据,至于为什么不能提供0.01的国家法律有明文规定小废这里就不再做说明了)

1.修正经纬度偏移的代码与算法:

 

 
  
  1. <?php 
  2. /* 
  3.    版本编号:101105082215 
  4.    文件名称:sql.php 
  5.    更新日期:2011-05-08 
  6.    代码修改:feikeq 
  7.    代码功能:利用0.01精度校正库文件修正经纬度偏移。 
  8. */ 
  9. header("Content-Type:text/html; charset=utf-8"); 
  10. define('__dat_db__' , 'offset.dat' );// DAT数据文件 
  11. define('datmax' , 9813675 );// 数据条数-结束记录 
  12.  
  13. //SELECT * FROM `offset_data` where lon=7350 and lat=3930 
  14.  
  15. // # xz.php?lat=39.914914&lon=116.460633  
  16. $lon=$_GET['lon']; 
  17. $lat=$_GET['lat']; 
  18. $tmplon=intval($lon * 100); 
  19. $tmplat=intval($lat * 100); 
  20. //经度到像素X值 
  21. function lngToPixel($lng,$zoom) { 
  22. return ($lng+180)*(256<<$zoom)/360; 
  23. //像素X到经度 
  24. function pixelToLng($pixelX,$zoom){ 
  25. return $pixelX*360/(256<<$zoom)-180; 
  26. //纬度到像素Y 
  27. function latToPixel($lat$zoom) { 
  28. $siny = sin($lat * pi() / 180); 
  29. $y=log((1+$siny)/(1-$siny)); 
  30. return (128<<$zoom)*(1-$y/(2*pi())); 
  31. //像素Y到纬度 
  32. function pixelToLat($pixelY$zoom) { 
  33. $y = 2*pi()*(1-$pixelY /(128 << $zoom)); 
  34. $z = pow(M_E, $y); 
  35. $siny = ($z -1)/($z +1); 
  36. return asin($siny) * 180/pi(); 
  37.  
  38.  
  39. function xy_fk( $number ){ 
  40.         $fp = fopen(__dat_db__,"rb"); //■1■.将 r 改为 rb 
  41.         $myxy=$number;#"112262582"
  42.         $left = 0;//开始记录 
  43.         $right = datmax;//结束记录 
  44.          
  45.         //开如用二分法来查找查数据 
  46.         while($left <= $right){ 
  47.             $recordCount =(floor(($left+$right)/2))*8; //取半 
  48.             //echo "运算:left=".$left." right=".$right." midde=".$recordCount."<br />"; 
  49.             @fseek ( $fp$recordCount , SEEK_SET ); //设置游标 
  50.             $c = fread($fp,8); //读8字节 
  51.             $lon = unpack('s',substr($c,0,2)); 
  52.             $lat = unpack('s',substr($c,2,2)); 
  53.             $x = unpack('s',substr($c,4,2)); 
  54.             $y = unpack('s',substr($c,6,2)); 
  55.             $jwd=$lon[1].$lat[1]; 
  56.             //echo "找到的经纬度:".$jwd; 
  57.             if ($jwd==$myxy){ 
  58.                fclose($fp); 
  59.                return $x[1]."|".$y[1]; 
  60.                break
  61.             }else if($jwd<$myxy){ 
  62.                //echo " > ".$myxy."<br />"; 
  63.                $left=($recordCount/8) +1; 
  64.             }else if($jwd>$myxy){ 
  65.                //echo " < ".$myxy."<br />"; 
  66.                $right=($recordCount/8) -1; 
  67.             } 
  68.                    
  69.         } 
  70.         fclose($fp); 
  71.  
  72. $offset =xy_fk($tmplon.$tmplat); 
  73. $off=explode('|',$offset); 
  74. $lngPixel=lngToPixel($lon,18)-$off[0]; 
  75. $latPixel=latToPixel($lat,18)-$off[1]; 
  76.  
  77. echo pixelToLat($latPixel,18).",".pixelToLng($lngPixel,18); 
  78.  
  79. ?> 


2.将地址文字采集字符经纬度并将字符经纬度解密成数字经纬度(这个示例用的是mapabc,当然你也可以用其它地图如google或mapbar等..)

 

 
  
  1. <?php 
  2. /* 
  3.    版本编号:101105091046 
  4.    文件名称:sql.php 
  5.    更新日期:2011-05-09 
  6.    代码修改:feikeq 
  7.    代码功能:将数据库内的地址文字采集字符经纬度并将字符经纬度解密成数字经纬度,然后利用0.01精度校正库文件修正经纬度偏移。 
  8. */ 
  9. header("Content-Type:text/html; charset=utf-8"); 
  10.     $mysql_server_name="localhost"; //数据库服务器名称 
  11.     $mysql_username="root"; // 连接数据库用户名 
  12.     $mysql_password=""; // 连接数据库密码 
  13.     $mysql_database="ycyw"; // 数据库的名字 
  14.    $mysql_table="ycyw_address_test"; // 数据表 
  15.    $start0 ;// 开始数据记录 
  16.    $over99999 ;// 结束数据记录 
  17.    //如果用原来的JS调用解密处理180条数据用时45秒左右现在只要15秒。 
  18.     
  19.    $phptime_1 = explode(' ', microtime()); 
  20. /* //        mapabc经纬度加密解密 - 开始            // */ 
  21. //MapAbc中使用编码坐标与10进度方式的坐标转换js方法,仅供参考 
  22. $__keys__ = array
  23.     array(0, 2, 1, 2, 8, 9, 4, 1, 7, 2, 5, 3, 9),  
  24.     array(0, 3, 2, 2, 9, 5, 8, 2, 6, 8, 4, 6, 3),  
  25.     array(1, 5, 2, 7, 1, 4, 7, 2, 4, 1, 4, 3, 0),  
  26.     array(0, 7, 8, 3, 4, 9, 0, 6, 7, 7, 4, 4, 2),  
  27.     array(0, 2, 1, 8, 4, 9, 3, 2, 3, 1, 5, 7, 8),  
  28.     array(0, 0, 9, 5, 4, 7, 3, 0, 8, 7, 5, 2, 8),  
  29.     array(0, 1, 5, 1, 1, 8, 2, 7, 1, 9, 1, 3, 5),  
  30.     array(0, 5, 2, 5, 6, 0, 3, 4, 6, 7, 1, 3, 5),  
  31.     array(1, 3, 2, 1, 8, 1, 8, 3, 7, 9, 2, 7, 0),  
  32.     array(1, 2, 7, 7, 4, 3, 1, 5, 5, 0, 6, 4, 4),  
  33.     array(1, 5, 2, 8, 9, 2, 5, 9, 6, 7, 3, 3, 5),  
  34.     array(1, 7, 9, 4, 5, 0, 9, 4, 9, 6, 1, 9, 9),  
  35.     array(0, 6, 8, 3, 3, 6, 3, 5, 2, 0, 0, 9, 1),  
  36.     array(1, 1, 1, 4, 7, 8, 6, 9, 6, 8, 8, 4, 6),  
  37.     array(0, 5, 2, 1, 2, 5, 7, 0, 0, 4, 7, 4, 1),  
  38.     array(0, 7, 6, 4, 2, 3, 9, 0, 7, 8, 5, 6, 7),  
  39.     array(0, 1, 7, 6, 0, 5, 4, 7, 6, 7, 7, 5, 7),  
  40.     array(0, 5, 2, 9, 8, 1, 7, 8, 3, 8, 5, 4, 5),  
  41.     array(0, 4, 3, 1, 2, 8, 3, 7, 0, 9, 4, 8, 8),  
  42.     array(1, 0, 6, 7, 9, 4, 3, 5, 2, 9, 8, 7, 7),  
  43.     array(1, 6, 4, 4, 6, 7, 1, 4, 4, 2, 6, 7, 5),  
  44.     array(0, 8, 1, 7, 7, 5, 2, 6, 4, 3, 9, 7, 5),  
  45.     array(1, 7, 0, 5, 6, 2, 5, 2, 7, 4, 6, 2, 8),  
  46.     array(0, 4, 9, 2, 3, 0, 5, 4, 7, 8, 7, 0, 5),  
  47.     array(1, 1, 0, 5, 1, 7, 2, 8, 7, 2, 6, 9, 3),  
  48.     array(1, 4, 2, 3, 6, 1, 5, 3, 2, 0, 3, 6, 2),  
  49.     array(1, 1, 6, 5, 1, 0, 6, 8, 9, 7, 1, 7, 9),  
  50.     array(0, 6, 5, 4, 0, 7, 1, 7, 6, 2, 5, 4, 2),  
  51.     array(1, 9, 8, 6, 6, 6, 8, 4, 5, 4, 0, 4, 0),  
  52.     array(1, 2, 7, 1, 5, 0, 6, 8, 0, 1, 3, 7, 9),  
  53.     array(1, 1, 6, 4, 9, 8, 6, 0, 6, 2, 1, 9, 8),  
  54.     array(0, 0, 1, 9, 5, 3, 3, 9, 6, 7, 4, 1, 1),  
  55.     array(0, 2, 8, 5, 7, 8, 6, 7, 3, 3, 1, 6, 4),  
  56.     array(1, 8, 2, 5, 8, 4, 7, 6, 8, 8, 5, 7, 6),  
  57.