| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | <?php /*    代码功能:利用0.01精度校正库文件修正中国地图经纬度偏移。 */ header("Content-Type:text/html; charset=utf-8"); define('__dat_db__' , 'offset.dat' );// DAT数据文件 define('datmax' , 9813675 );// 数据条数-结束记录 // # offset.php?lat=39.914914&lon=116.460633 $lon=$_GET['lon']; $lat=$_GET['lat']; $tmplon=intval($lon * 100); $tmplat=intval($lat * 100); //经度到像素X值 function lngToPixel($lng,$zoom) { return ($lng+180)*(256<<$zoom)/360; } //像素X到经度 function pixelToLng($pixelX,$zoom){ return $pixelX*360/(256<<$zoom)-180; } //纬度到像素Y function latToPixel($lat, $zoom) { $siny = sin($lat * pi() / 180); $y=log((1+$siny)/(1-$siny)); return (128<<$zoom)*(1-$y/(2*pi())); } //像素Y到纬度 function pixelToLat($pixelY, $zoom) { $y = 2*pi()*(1-$pixelY /(128 << $zoom)); $z = pow(M_E, $y); $siny = ($z -1)/($z +1); return asin($siny) * 180/pi(); } function xy_fk( $number ){         $fp = fopen(__dat_db__,"rb"); //■1■.将 r 改为 rb         $myxy=$number;//#"112262582";         $left = 0;//开始记录         $right = datmax;//结束记录         //采用用二分法来查找查数据         while($left <= $right){             $recordCount =(floor(($left+$right)/2))*8; //取半             //echo "运算:left=".$left." right=".$right." midde=".$recordCount." ";             @fseek ( $fp, $recordCount , SEEK_SET ); //设置游标             $c = fread($fp,8); //读8字节             $lon = unpack('s',substr($c,0,2));             $lat = unpack('s',substr($c,2,2));             $x = unpack('s',substr($c,4,2));             $y = unpack('s',substr($c,6,2));             $jwd=$lon[1].$lat[1];             //echo "找到的经纬度:".$jwd;             if ($jwd==$myxy){                fclose($fp);                return $x[1]."|".$y[1];                break;             }else if($jwd<$myxy){                //echo " > ".$myxy." ";                $left=($recordCount/8) +1;             }else if($jwd>$myxy){                //echo " < ".$myxy." ";                $right=($recordCount/8) -1;             }         }         fclose($fp); } $offset =xy_fk($tmplon.$tmplat); $off=explode('|',$offset); $lngPixel=lngToPixel($lon,18)+$off[0]; $latPixel=latToPixel($lat,18)+$off[1]; echo pixelToLat($latPixel,18).",".pixelToLng($lngPixel,18); ?> | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | using System; using System.Collections.Generic; using System.Linq; using System.Text;    namespace MapDigit.GIS {     public class GeoLatLng     {            public GeoLatLng(double latitude, double longitude)         {             this.latitude = latitude;             this.longitude = longitude;         }         public double latitude;         public double longitude;     }        public class GeoPoint     {         public GeoPoint(int x, int y)         {             this.x = x;             this.y = y;         }         public int x;         public int y;     }        public class OffsetInChina     {         //用于从GPS坐标转换为偏移后坐标         public static GeoLatLng fromEarthToMars(GeoLatLng earth)         {             GeoPoint ptOffset = getOffset(earth.latitude, earth.longitude);             if (ptOffset.x != 0 || ptOffset.y != 0)             {                 int pixelX, pixelY;                 TileSystem.LatLongToPixelXY(earth.latitude, earth.longitude, 18, out pixelX, out pixelY);                 GeoPoint pt = new GeoPoint(pixelX, pixelY);                 pt.x += ptOffset.x;                 pt.y += ptOffset.y;                 double latitude, longitude;                 TileSystem.PixelXYToLatLong(pt.x, pt.y, 18, out latitude, out longitude);                 return new GeoLatLng(latitude, longitude);                }             else             {                 return new GeoLatLng(earth.latitude, earth.longitude);             }            }            //用于将偏移后坐标转成真实的坐标         public static GeoLatLng fromMarToEarth(GeoLatLng mars)         {             GeoPoint ptOffset = getOffset(mars.latitude, mars.longitude);             if (ptOffset.x != 0 || ptOffset.y != 0)             {                 int pixelX, pixelY;                 TileSystem.LatLongToPixelXY(mars.latitude, mars.longitude, 18, out pixelX, out pixelY);                 GeoPoint pt = new GeoPoint(pixelX, pixelY);                 pt.x -= ptOffset.x;                 pt.y -= ptOffset.y;                 double latitude, longitude;                 TileSystem.PixelXYToLatLong(pt.x, pt.y, 18, out latitude, out longitude);                 return new GeoLatLng(latitude, longitude);                }             else             {                 return new GeoLatLng(mars.latitude, mars.longitude);             }         }            //这个函数用于将需要查询的经纬度转成最近的0.01分度值,无插值         //也可以自行实现插值         private static GeoPoint getQueryLocation(double latitude, double longitude)         {             int lat = (int)(latitude * 100);             int lng = (int)(longitude * 100);             double lat1 = ((int)(latitude * 1000 + 0.499999)) / 10.0;             double lng1 = ((int)(longitude * 1000 + 0.499999)) / 10.0;             for (double x = longitude; x < longitude + 1; x += 0.5)             {                 for (double y = latitude; x < latitude + 1; y += 0.5)                 {                     if (x <= lng1 && lng1 < (x + 0.5) && lat1 >= y && lat1 < (y + 0.5))                     {                         return new GeoPoint((int)(x + 0.5), (int)(y + 0.5));                     }                 }             }             return new GeoPoint(lng, lat);         }            private static GeoPoint getOffset(double longitude, double latitude)         {             //这个函数用于返回查询结果,就是从校正数据中返回18级时x,y方偏移             //可以自行实现             return null;         }        } } |